将存储在 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 的更多说明。

您可以通过许多其他方式做到这一点:

  1. REGEXP_SUBSTR
  2. XML
  3. Table 函数
  4. 流水线函数

我已经在这里回答了

你可以使用 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 ||',%'