2009-06-09 61 views
0

我在程序有一個簡單的Oracle聲明:的Oracle PL/SQL ORA-01722錯誤

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」。

當我運行該語句輸出存儲過程thenn它運行良好,但是當我運行一個存儲過程,我得到上面的行話說無效的號碼錯誤。

任何線索?

回答

2

您不能使用「的」條款與這樣的一個變量。它周圍的一種方法是

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; 
1

如果v_qstns_to_delete是一個varchar,你需要它有點轉換讓Oracle瞭解,有可能是它的幾個項目。一種方法是將字符串轉換爲項目表。

假設qstn_id是一個數列,你會:

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

COLUMN_VALUE 
------------ 
      24 
      43 
      23 
      44 
      21 

要做到在列表的變量:

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 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同一主題。