将存储在PL / SQL变量中的值传递给IN子句

时间:2015-02-26 08:13:55

标签: oracle plsql oracle11g

我的代码如下:

DECLARE
vr_arr_list VARCHAR2(100) := `7,3,4';
BEGIN
FOR CX IN (Select ID, NAME from TBL_DEMO where ID IN (vr_arr_list))
LOOP
DBMS_OUTPUT.PUT_LINE(CX.ID || '-' || CX.NAME);
END LOOP;
/

我也尝试过使用

DBMS_UTILITY.comma_to_table (list => REGEXP_REPLACE (vr_arr_list, '(^|,)','\1x'), tablen => l_ID_count, tab => l_ID_array);

但传递数组l_ID_array也不起作用。

请帮忙。

5 个答案:

答案 0 :(得分:2)

  

其中ID IN(vr_arr_list)

WHERE子句中的值是不同的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. 表格功能
  4. 流水线功能
  5. 我已在这里回答https://stackoverflow.com/a/26273192/3989608

    您可以使用 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

答案 1 :(得分:2)

另一种方法是将嵌套表与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;

答案 2 :(得分:1)

您只需使用MEMBER OF关键字即可。但是,输入必须是UDT(嵌套表)

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)
..

答案 3 :(得分:0)

你不能这样做。查询的绑定变量数必须才能修复。 Oracle查询得到优化,编译,您可以重用exec。多次计划。但每次调用必须使用相同数量的绑定变量。 Oracle甚至可能会创建不同的(更好的)exec。计划在IN子句中有多个值的查询。

所以这个:

Select ID, NAME from TBL_DEMO where ID IN (?,?);

和此:

Select ID, NAME from TBL_DEMO where ID IN (?,?,?);

永远不会有相同的exec。计划ID。 Lalit的回答中提到了如何绕过这种限制的方法。

答案 4 :(得分:0)

有更简单的方法可以做到这一点:

Select ID, NAME from TBL_DEMO where  ','||vr_arr_list||',' like '%,'|| ID ||',%'