Reputation: 30424
I have a simple oracle statement in my procedure:
update org.security_training_question a
set a.actv_indr = 'N' where a.qstn_id in (v_qstns_to_delete);
v_qstns_to_delete is a parameter being passed. It is a varchar2 field and a.qstn_id is a numeric field.
When calling the Stored Procedure, for v_qstns_to_delete I am passing the following String: "24, 43, 23, 44, 21".
When I run the statement output the stored procedure thenn it runs fine but when I run it as a stored procedure I get an error on the above line saying Invalid Number.
Any clue?
Upvotes: 0
Views: 1614
Reputation: 67802
if v_qstns_to_delete
is a varchar, you would need to convert it somewhat to let Oracle understand that there may be several items in it. One method would be to convert the string to a table of items.
Supposing qstn_id
is a NUMBER column, you would:
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
You could then convert a string to a table of number from SQL:
SQL> SELECT * FROM TABLE(to_tab_number('24, 43, 23, 44, 21'));
COLUMN_VALUE
------------
24
43
23
44
21
To do a variable in-list:
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
More on the same subject on askTom.
Upvotes: 1
Reputation: 36987
You can't use a "in" clause with a variable like that. One way around it is
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;
Upvotes: 2