【问题标题】:oracle pl/sql ora-01722 errororacle pl/sql oracle-01722 错误
【发布时间】:2011-04-17 09:50:51
【问题描述】:

我的程序中有一个简单的 oracle 语句:

update org.security_training_question a 
set a.actv_indr = 'N' where a.qstn_id in (v_qstns_to_delete);

v_qstns_to_delete 是一个正在传递的参数。它是一个 varchar2 字段,a.qstn_id 是一个数字字段。

在调用存储过程时,对于 v_qstns_to_delete,我将传递以下字符串:“24, 43, 23, 44, 21”。

当我运行语句输出存储过程时,它运行良好,但是当我将它作为存储过程运行时,我在上面的行中收到一个错误,提示数字无效。

有什么线索吗?

【问题讨论】:

    标签: sql oracle ora-01722


    【解决方案1】:

    您不能将“in”子句与这样的变量一起使用。一种解决方法是

    declare stmt varchar2(4000);
    begin
      stmt := 'update org.security_training_question a set a.actv_indr = ''N'' where a.qstn_id in ('||v_qstns_to_delete||')';
      execute immediate stmt;
    end;
    

    【讨论】:

      【解决方案2】:

      如果v_qstns_to_delete 是一个varchar,您需要对其进行一些转换以让Oracle 了解其中可能有多个项目。一种方法是将字符串转换为项目表。

      假设 qstn_id 是一个 NUMBER 列,您会:

      SQL> CREATE TYPE tab_number AS TABLE OF NUMBER;
        2  /
      
      Type created
      
      SQL> CREATE OR REPLACE FUNCTION to_tab_number(p_in VARCHAR2,
        2                                           p_separator VARCHAR2 DEFAULT ',')
        3        RETURN tab_number AS
        4     l_result tab_number := tab_number();
        5     l_tail   LONG := p_in;
        6  BEGIN
        7     WHILE l_tail IS NOT NULL LOOP
        8        l_result.EXTEND;
        9        IF instr(l_tail, p_separator) != 0 THEN
       10           l_result(l_result.COUNT) := to_number(substr(l_tail,
       11                                                 1,
       12                                                 instr(l_tail, p_separator) - 1));
       13           l_tail := substr(l_tail, instr(l_tail, p_separator) + 1);
       14        ELSE
       15           l_result(l_result.COUNT) := to_number(l_tail);
       16           l_tail := NULL;
       17        END IF;
       18     END LOOP;
       19     RETURN l_result;
       20  END;
       21  /
      
      Function created
      

      然后您可以将字符串从 SQL 转换为数字表:

      SQL> SELECT * FROM TABLE(to_tab_number('24, 43, 23, 44, 21'));
      
      COLUMN_VALUE
      ------------
                24
                43
                23
                44
                21
      

      在列表中做一个变量:

      SQL> SELECT object_id, owner
        2    FROM all_objects
        3   WHERE object_id IN (SELECT column_value FROM TABLE(to_tab_number('18,19,20')));
      
       OBJECT_ID OWNER
      ---------- ------------------------------
              18 SYS
              19 SYS
              20 SYS
      

      askTom 上有关同一主题的更多信息。

      【讨论】:

        猜你喜欢
        • 2012-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-28
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多