2009-06-09 5 views
0

J'ai une simple déclaration d'oracle dans ma procédure:oracle pl/sql ora-01722 erreur

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

v_qstns_to_delete est un paramètre étant passé. C'est un champ varchar2 et un .qstn_id est un champ numérique. Lors de l'appel de la procédure stockée, pour v_qstns_to_delete, je passe la chaîne suivante: "24, 43, 23, 44, 21".

Lorsque j'exécute la sortie d'instruction, la procédure stockée fonctionne correctement, mais lorsque je la lance en tant que procédure stockée, j'obtiens une erreur sur la ligne ci-dessus indiquant le numéro invalide.

Une idée?

Répondre

2

Vous ne pouvez pas utiliser une clause "in" avec une variable de ce type. Une façon de contourner est

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

si v_qstns_to_delete est un varchar, vous devez convertir un peu pour laisser comprendre Oracle qu'il peut y avoir plusieurs éléments qu'il contient. Une méthode consisterait à convertir la chaîne en une table d'éléments.

Supposant qstn_id est une colonne numérique, vous devez:

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 

Vous pouvez ensuite convertir une chaîne à une table de nombre de SQL:

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

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

Pour faire une variable dans la liste:

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 

Plus sur le même sujet sur askTom.

Questions connexes