【问题标题】:passing variable value in pl/sql query block在 pl/sql 查询块中传递变量值
【发布时间】:2016-08-23 20:43:19
【问题描述】:

我遇到了一个问题。请需要您的专业知识..

PL/SQL 块包含一个变量 p_user_id varchar(50)

值设置为低于值

p_user_id := '101,102,103';

我在 PL/SQl 块中有如下查询

select Count(*) into v_count
from users
where user_id not in (p_user_id);

每次我调用这个 PL/SQL 块时,v_count 值都是相同的,即用户表中的记录总数。 Not In 子句无法正常工作。请帮忙。

【问题讨论】:

  • In clause doesn't work properly 它可以正常工作。您没有将值列表传递给 in 子句,您只传递了一个值 -'101,102,103'

标签: sql oracle plsql


【解决方案1】:

使用LIKE字符串比较:

DECLARE
  p_user_id VARCHAR2(200) := '101,102,103';
  v_count   INT;
BEGIN
  SELECT Count(*)
  INTO   v_count
  FROM   users
  WHERE  ',' || p_user_id || ',' NOT LIKE '%,' || user_id || ',%';
END;
/

使用集合:

CREATE OR REPLACE TYPE intlist IS TABLE OF INT;
/

DECLARE
  p_user_id INTLIST := INTLIST( 101, 102, 103 );
  v_count   INT;
BEGIN
  SELECT Count(*)
  INTO   v_count
  FROM   users
  WHERE  user_id NOT MEMBER OF p_user_id;
END;
/

【讨论】:

    【解决方案2】:

    users 表中没有 user_id 的值为“101,102,103”的行。

    如果您想将一个字符串拆分为一组单独的值,您需要做的不仅仅是在not in 表达式中使用它。

    一些可能的方法:

    declare
       p_csvlist varchar2(100) := '2002, 7369, 7499, 7902, 7934';
       v_count integer;
    begin
       select count(*) into v_count
       from   emp e
       where  e.empno in
              ( select extractvalue(xt.column_value,'e')
                from   table(xmlsequence
                       ( extract
                         ( xmltype('<coll><e>' || replace(p_csvlist,',','</e><e>') || '</e></coll>')
                         , '/coll/*') )) xt );
    
       dbms_output.put_line(v_count || ' rows');
    end;
    

    或者这个

    declare
       p_csvlist varchar2(100) := '2002, 7369, 7499, 7902, 7934';
       v_count integer;
    begin
       select count(*) into v_count
       from   emp e
       where  e.empno in
              ( select regexp_substr(p_csvlist, '[^,]+',1,rownum)
                from   dual
                connect by rownum <= length(p_csvlist) - length(replace(p_csvlist,',')) );
    
       dbms_output.put_line(v_count || ' rows');
    end;
    

    或者这个(仅适用于数值):

    declare
       p_csvlist varchar2(100) := '2002, 7369, 7499, 7902, 7934';
       v_count integer;
    begin
       select count(*) into v_count
       from   emp e
       where  e.empno in
              ( select to_number(xt.column_value)
                from   xmltable(p_csvlist) xt );
    
       dbms_output.put_line(v_count || ' rows');
    end;
    

    示例来自我的常见问题解答文章: www.williamrobertson.net/documents/comma-separated.html

    【讨论】:

    • 请避免链接到外部网站(特别是如果您尚未声明您与该网站的隶属关系)。在帖子中包含所有相关信息。
    • 好点。从链接页面添加了代码示例(来自我自己的网站,如果你是这个意思)。
    【解决方案3】:

    您可以使用 sys.DBMS_DEBUG_VC2COLL --Oracle 自己提供的集合数据类型

      DECLARE
          p_user_id sys.DBMS_DEBUG_VC2COLL := sys.DBMS_DEBUG_VC2COLL( 101, 102, 103 );
          v_count   INT;
        BEGIN
          SELECT Count(*)
          INTO   v_count
          FROM   users
          WHERE  user_id not in(select * from table(p_user_id));
        END;
        /
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 2016-02-14
      • 2012-01-18
      相关资源
      最近更新 更多