【问题标题】:PL/SQL - comma separated list within IN CLAUSEPL/SQL - IN CLAUSE 中的逗号分隔列表
【发布时间】:2012-09-29 19:02:06
【问题描述】:

我无法让一段 pl/sql 代码工作。在我的程序的顶部,我从我的 oracle apex 应用程序中获取了一些关于选中哪些复选框的数据。因为包含复选框的报告是动态生成的,所以我必须遍历

APEX_APPLICATION.G_F01 

列出并生成一个逗号分隔的字符串,如下所示

v_list VARCHAR2(255) := (1,3,5,9,10);

我想稍后再查询该列表并将 v_list 放在 IN 子句中,就像这样

SELECT * FROM users 
WHERE user_id IN (v_list);

这当然会引发错误。我的问题是我可以将 v_list 转换为什么,以便能够将其插入到 pl/sql 过程中查询的 IN 子句中?

【问题讨论】:

    标签: plsql oracle-apex


    【解决方案1】:

    如果users 很小且user_id 不包含逗号,则可以使用:

    SELECT * FROM users WHERE ',' || v_list || ',' LIKE '%,'||user_id||',%'
    

    这个查询不是最优的,因为它不能在user_id上使用索引。

    我建议您使用一个流水线函数,该函数返回一个您可以直接查询的NUMBER 表。例如:

    CREATE TYPE tab_number IS TABLE OF NUMBER;
    /
    CREATE OR REPLACE FUNCTION string_to_table_num(p VARCHAR2)
       RETURN tab_number
       PIPELINED IS
    BEGIN
       FOR cc IN (SELECT rtrim(regexp_substr(str, '[^,]*,', 1, level), ',') res
                    FROM (SELECT p || ',' str FROM dual)
                  CONNECT BY level <= length(str) 
                                      - length(replace(str, ',', ''))) LOOP
          PIPE ROW(cc.res);
       END LOOP;
    END;
    /
    

    然后您将能够构建查询,例如:

    SELECT * 
      FROM users 
     WHERE user_id IN (SELECT *
                         FROM TABLE(string_to_table_num('1,2,3,4,5'));
    

    【讨论】:

      【解决方案2】:

      你可以使用XMLTABLE如下

      SELECT * FROM users 
      WHERE user_id IN (SELECT to_number(column_value) FROM XMLTABLE(v_list));
      

      【讨论】:

        【解决方案3】:

        我也试图找到解决方案,但从未成功。您可以将查询构建为字符串,然后运行 ​​EXECUTE IMMEDIATE,请参阅http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/dynamic.htm#i14500

        也就是说,我突然想到 IN 子句的参数可以是子选择:

        SELECT * FROM users 
        WHERE user_id IN (SELECT something FROM somewhere)
        

        那么,是否可以将复选框值公开为存储函数?然后你也许可以做类似的事情

        SELECT * FROM users
        WHERE user_id IN (SELECT my_package.checkbox_func FROM dual)
        

        【讨论】:

          【解决方案4】:

          就个人而言,我喜欢这种方法:

          with t as (select 'a,b,c,d,e' str from dual)
          --
          select val
          from t, xmltable('/root/e/text()'
                           passing xmltype('<root><e>' || replace(t.str,',','</e><e>')|| '</e></root>')
                           columns val varchar2(10) path '/'
                          )
          

          可以在Thread: Split Comma Delimited String Oracle 中找到其他示例

          如果您想了解更多选项,请访问 OTN plsql 论坛。

          【讨论】:

            猜你喜欢
            • 2011-10-25
            • 2012-04-19
            • 1970-01-01
            • 2018-08-07
            • 1970-01-01
            • 2012-01-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多