CREATE OR REPLACE FUNCTION PARSER_FUNCTION(
inputString IN VARCHAR2,
index IN NUMBER
)
RETURN VARCHAR2 DETERMINISTIC
AS
RETURN REGEXP_SUBSTR(inputString, '[[:alpha:]]+', 1, index);
END PARSER_FUNCTION;
/
Или, без регулярных выражений:
CREATE OR REPLACE FUNCTION parser_function(
list IN VARCHAR2,
position IN NUMBER,
delimiter IN VARCHAR2 DEFAULT ','
)
RETURN VARCHAR2 DETERMINISTIC
IS
p_start NUMBER := 1;
p_end NUMBER;
BEGIN
IF list IS NULL OR position < 1 THEN
RETURN NULL;
END IF;
IF position > 1 THEN
p_start := INSTR(list, delimiter, 1, position - 1) + 1;
IF p_start = 1 THEN
RETURN NULL;
END IF;
END IF;
p_end := INSTR(list, delimiter, 1, position);
IF p_end = 0 THEN
p_end := LENGTH(list) + 1;
END IF;
RETURN SUBSTR(list, p_start, p_end - p_start);
END;
/
Тогда вы можете просто сделать:
WHERE table_column LIKE '%' || PARSER_FUNCTION('list,list2,list3', 1) || '%'
AND table_column LIKE '%' || PARSER_FUNCTION('list,list2,list3', 2) || '%'
AND table_column LIKE '%' || PARSER_FUNCTION('list,list2,list3', 3) || '%'
AND table_column LIKE '%' || PARSER_FUNCTION('list,list2,list3', 4) || '%'
AND table_column LIKE '%' || PARSER_FUNCTION('list,list2,list3', 5) || '%'
(Примечание: Это будет работать, если вы используете AND
в ИНЕКЕ но не может, когда вы используете OR
, так как 4-й и 5-й записи в списке не существуют, поэтому вы получите предложение AND table_column LIKE '%%'
wh Ich всегда будет истинным, так что вам может понадобиться немного более оборонительный кодирование, чтобы проверить, если возврат из PARSER_FUNCTION
не NULL
)
Или вы могли бы просто избавиться от функции:.
WHERE table_column LIKE '%' || REGEXP_SUBSTR('list,list2,list3', '[[:alpha:]]+', 1, 1) || '%'
AND table_column LIKE '%' || REGEXP_SUBSTR('list,list2,list3', '[[:alpha:]]+', 1, 2) || '%'
AND table_column LIKE '%' || REGEXP_SUBSTR('list,list2,list3', '[[:alpha:]]+', 1, 3) || '%'
AND table_column LIKE '%' || REGEXP_SUBSTR('list,list2,list3', '[[:alpha:]]+', 1, 4) || '%'
AND table_column LIKE '%' || REGEXP_SUBSTR('list,list2,list3', '[[:alpha:]]+', 1, 5) || '%'
Обновление:
Вы также можете конвертировать список коллекции и присоединиться, что ваш запрос:
CREATE OR REPLACE FUNCTION split_String(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT ','
) RETURN SYS.ODCIVARCHAR2LIST DETERMINISTIC
AS
p_result SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH(i_str);
c_ld CONSTANT NUMBER(5) := LENGTH(i_delim);
BEGIN
IF c_len > 0 THEN
p_end := INSTR(i_str, i_delim, p_start);
WHILE p_end > 0 LOOP
p_result.EXTEND;
p_result(p_result.COUNT) := SUBSTR(i_str, p_start, p_end - p_start);
p_start := p_end + c_ld;
p_end := INSTR(i_str, i_delim, p_start);
END LOOP;
IF p_start <= c_len + 1 THEN
p_result.EXTEND;
p_result(p_result.COUNT) := SUBSTR(i_str, p_start, c_len - p_start + 1);
END IF;
END IF;
RETURN p_result;
END;
/
Тогда вы можете просто сделать:
SELECT *
FROM your_table t
WHERE NOT EXISTS(SELECT 1
FROM TABLE(split_String('list1,list2,list3') l
WHERE t.table_column NOT LIKE '%' || l.COLUMN_VALUE || '%')
Это означает, что ваш список может содержать любое количество элементов, и он будет проверять их все без неоднократно называть извлечение элемента списка с помощью регулярных выражений.
Мне нужно было вызвать функцию из четырех разных хранимых процедур. Я заставлял себя думать, что в любое время, когда мне нужно использовать процесс более одного раза, мне нужно модулизировать процесс. Еще раз взглянув на мою проблему, я думаю, что избавление от этой функции было правильным. Большое спасибо. – Jake
Ваше регулярное выражение не работает с элементом списка NULL, но возвращает неправильное значение.Попробуйте, где ожидается третий элемент «listC», а второй элемент - NULL: 'с tbl (col1) as ( выберите« listA ,, listC, listD »из двойного ) выберите REGEXP_SUBSTR (col1, '[[[ : alpha:]] + ', 1, 3) от tbl; ' –
Итак, вы бы исправили регулярное выражение один раз, в своей функции или много раз по всему вашему коду? Придерживайтесь своего первоначального инстинкта! –