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
(注意:当您在 where 子句中使用时,这将起作用,但当您使用时可能不起作用,OR
因为列表中的第 4 和第 5 个条目不存在,因此您将得到一个AND table_column LIKE '%%'
始终为 true 的子句,因此您可能需要更多的防御性编码来检查从返回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 || '%' )
这意味着您的列表可以包含任意数量的元素,它将检查所有元素,而无需使用正则表达式重复调用提取列表项。