尝试概括SQL将字符串/ varchar拆分为记录的内容。这是工作SQL:
SELECT test.* FROM test JOIN (
SELECT level nbr, REGEXP_SUBSTR('1,3', '(.*?)(,|$)', 1, level, NULL, 1) value
FROM dual CONNECT BY level <= REGEXP_COUNT('1,3', ',')+1 ORDER BY level
) requested ON test.id=requested.value
我的意思是概括;将重复的SQL(在这种情况下,括号中的位从上面的工作SQL中移动)移动到过程/函数,以便可以重用它。在这种情况下,我试图找到一种方法来插入生成的内部select语句。这就是通用SQL的外观:
SELECT t.* FROM table t JOIN (<GENERATED_INNER_SELECT>) my ON t.x=my.x;
但是我还没有成功,我试过但是调用我的函数生成内部select语句直接导致:
ORA-00900:无效的SQL语句
使用通用SQL中的函数导致:
ORA-00907:缺少右括号
在这种情况下,这些错误都不会对我有任何意义。
也许你可以帮忙吗? check out the full case on dbfiddle
答案 0 :(得分:4)
如果生成要用作子查询的SQL片段,那么将其作为子查询嵌入的整体语句也必须动态执行。
让函数实际执行拆分并返回集合 - 作为模式级集合类型会更简单:
CREATE TYPE T_NUMBERS AS TABLE OF NUMBER
/
CREATE OR REPLACE FUNCTION split(p_string VARCHAR2, p_seperator VARCHAR2 DEFAULT ',')
RETURN T_NUMBERS AS
L_NUMBERS T_NUMBERS;
BEGIN
SELECT REGEXP_SUBSTR(p_string, '(.*?)(,|$)', 1, level, NULL, 1)
BULK COLLECT INTO L_NUMBERS
FROM dual
CONNECT BY level <= REGEXP_COUNT(p_string, ',')+1;
RETURN L_NUMBERS;
END split;
/
SELECT * FROM TEST
WHERE id MEMBER OF (split('1,3'))
/
ID NAM
---------- ---
1 foo
3 foe
或者如果您更喜欢表集合表达式方法:
SELECT t.*
FROM TABLE(split('1,3')) tmp
JOIN test t ON t.id = tmp.column_value;
如果可以首先使用一组数字调用查询,但是如果没有看到调用是如何进行的 - 并且生成的字符串 - 很难准确地说出你是怎么回事,那就更简单了#39;需要改变它。您甚至可以使用内置集合类型,而不必定义自己的集合类型:
SELECT t.*
FROM TABLE(SYS.ODCINUMBERLIST(1,3)) tmp
JOIN test t ON t.id = tmp.column_value;
但它依赖于调用者能够传递数字而不是字符串(注意缺少单引号...)