将存储在 PL/SQL 变量中的值传递给 IN 子句
Pass value stored in a PL/SQL variable into an IN clause
我有如下代码:
宣布
vr_arr_list VARCHAR2(100) := ‘7,3,4’;
开始
FOR CX IN (Select ID, NAME from TBL_DEMO where ID IN (vr_arr_list))
环形
DBMS_OUTPUT.PUT_LINE(CX.ID || '-' || CX.NAME);
结束循环;
/
我也试过使用
DBMS_UTILITY.comma_to_table (list => REGEXP_REPLACE (vr_arr_list, '(^|,)', '\1x'), tablen => l_ID_count, tab => l_ID_array);
但是传递数组 l_ID_array 也没有用。
请提供帮助。
where ID IN (vr_arr_list)
它是 WHERE 子句中值的 Varying IN 列表。 IN (‘1, 2, 3′)
与 IN (1, 2, 3)
或 IN(‘1′, ‘2’, ‘3’)
不同。请参阅有关 Varying IN list of values in WHERE clause 的更多说明。
您可以通过许多其他方式做到这一点:
- REGEXP_SUBSTR
- XML
- Table 函数
- 流水线函数
我已经在这里回答了
你可以使用 DBMS_UTILITY.comma_to_table.
SQL> set serveroutput on;
SQL> DECLARE
2 l_tablen BINARY_INTEGER;
3 l_tab DBMS_UTILITY.uncl_array;
4 CURSOR cur
5 IS
6 SELECT 'word1, word2, word3, word4, word5, word6' val FROM dual;
7 rec cur%rowtype;
8 BEGIN
9 OPEN cur;
10 LOOP
11 FETCH cur INTO rec;
12 EXIT
13 WHEN cur%notfound;
14 DBMS_UTILITY.comma_to_table (
15 list => rec.val, tablen => l_tablen, tab => l_tab);
16 FOR i IN 1 .. l_tablen
17 LOOP
18 DBMS_OUTPUT.put_line(i || ' : ' || trim(l_tab(i)));
19 END LOOP;
20 END LOOP;
21 CLOSE cur;
22 END;
23 /
1 : word1
2 : word2
3 : word3
4 : word4
5 : word5
6 : word6
PL/SQL procedure successfully completed.
SQL>
还有其他方法,可以参考我的演示here。
另一种方法是将嵌套表与 TABLE 运算符
结合使用
create type nt_vr_arr_list is table of number;
DECLARE
vr_arr_list nt_vr_arr_list := nt_vr_arr_list(100, 200, 330);
BEGIN
FOR cx IN (SELECT id, name
FROM tbl_demo
WHERE id IN (SELECT COLUMN_VALUE FROM TABLE(vr_arr_list))) LOOP
DBMS_OUTPUT.put_line('ID: ' || cx.id || ' Name: ' || cx.name);
END LOOP;
END;
你不能那样做。查询的绑定变量数 必须 固定。 Oracle 查询得到优化、编译,您可以重用 exec。多次计划。但是每次调用必须使用相同数量的绑定变量。 Oracle 甚至可能创建不同的(更好的)执行程序。计划在 IN
子句中有很多值的查询。
所以这个:
Select ID, NAME from TBL_DEMO where ID IN (?,?);
还有这个:
Select ID, NAME from TBL_DEMO where ID IN (?,?,?);
永远不能有相同的执行官。计划编号。 Lalit 的回答中提到了绕过此限制的方法。
为此您可以简单地使用 MEMBER OF
关键字。但是,输入必须是 UDT
(嵌套 table)
CREATE TYPE my_array IS TABLE OF NUMBER;
DECLARE
vr_arr_list my_array := my_array(7, 3, 4);
BEGIN
FOR CX IN (Select ID, NAME from TBL_DEMO
where ID MEMBER OF vr_arr_list)
..
有更简单的方法可以做到这一点:
Select ID, NAME from TBL_DEMO where ','||vr_arr_list||',' like '%,'|| ID ||',%'
我有如下代码:
宣布 vr_arr_list VARCHAR2(100) := ‘7,3,4’; 开始 FOR CX IN (Select ID, NAME from TBL_DEMO where ID IN (vr_arr_list)) 环形 DBMS_OUTPUT.PUT_LINE(CX.ID || '-' || CX.NAME); 结束循环; /
我也试过使用
DBMS_UTILITY.comma_to_table (list => REGEXP_REPLACE (vr_arr_list, '(^|,)', '\1x'), tablen => l_ID_count, tab => l_ID_array);
但是传递数组 l_ID_array 也没有用。
请提供帮助。
where ID IN (vr_arr_list)
它是 WHERE 子句中值的 Varying IN 列表。 IN (‘1, 2, 3′)
与 IN (1, 2, 3)
或 IN(‘1′, ‘2’, ‘3’)
不同。请参阅有关 Varying IN list of values in WHERE clause 的更多说明。
您可以通过许多其他方式做到这一点:
- REGEXP_SUBSTR
- XML
- Table 函数
- 流水线函数
我已经在这里回答了
你可以使用 DBMS_UTILITY.comma_to_table.
SQL> set serveroutput on;
SQL> DECLARE
2 l_tablen BINARY_INTEGER;
3 l_tab DBMS_UTILITY.uncl_array;
4 CURSOR cur
5 IS
6 SELECT 'word1, word2, word3, word4, word5, word6' val FROM dual;
7 rec cur%rowtype;
8 BEGIN
9 OPEN cur;
10 LOOP
11 FETCH cur INTO rec;
12 EXIT
13 WHEN cur%notfound;
14 DBMS_UTILITY.comma_to_table (
15 list => rec.val, tablen => l_tablen, tab => l_tab);
16 FOR i IN 1 .. l_tablen
17 LOOP
18 DBMS_OUTPUT.put_line(i || ' : ' || trim(l_tab(i)));
19 END LOOP;
20 END LOOP;
21 CLOSE cur;
22 END;
23 /
1 : word1
2 : word2
3 : word3
4 : word4
5 : word5
6 : word6
PL/SQL procedure successfully completed.
SQL>
还有其他方法,可以参考我的演示here。
另一种方法是将嵌套表与 TABLE 运算符
结合使用create type nt_vr_arr_list is table of number;
DECLARE
vr_arr_list nt_vr_arr_list := nt_vr_arr_list(100, 200, 330);
BEGIN
FOR cx IN (SELECT id, name
FROM tbl_demo
WHERE id IN (SELECT COLUMN_VALUE FROM TABLE(vr_arr_list))) LOOP
DBMS_OUTPUT.put_line('ID: ' || cx.id || ' Name: ' || cx.name);
END LOOP;
END;
你不能那样做。查询的绑定变量数 必须 固定。 Oracle 查询得到优化、编译,您可以重用 exec。多次计划。但是每次调用必须使用相同数量的绑定变量。 Oracle 甚至可能创建不同的(更好的)执行程序。计划在 IN
子句中有很多值的查询。
所以这个:
Select ID, NAME from TBL_DEMO where ID IN (?,?);
还有这个:
Select ID, NAME from TBL_DEMO where ID IN (?,?,?);
永远不能有相同的执行官。计划编号。 Lalit 的回答中提到了绕过此限制的方法。
为此您可以简单地使用 MEMBER OF
关键字。但是,输入必须是 UDT
(嵌套 table)
CREATE TYPE my_array IS TABLE OF NUMBER;
DECLARE
vr_arr_list my_array := my_array(7, 3, 4);
BEGIN
FOR CX IN (Select ID, NAME from TBL_DEMO
where ID MEMBER OF vr_arr_list)
..
有更简单的方法可以做到这一点:
Select ID, NAME from TBL_DEMO where ','||vr_arr_list||',' like '%,'|| ID ||',%'