Sie können die kommagetrennte Liste als Parameter (Bind-Variable) übergeben, aber Sie sind dafür verantwortlich, sie in einer Unterabfrage zu analysieren. Eine Lösung basierend auf diesem Thread verwendet regexp_substr.
CREATE or REPLACE PROCEDURE p_getdata(A IN VARCHaR2, cur OUT sys_refcursor)
AS
BEGIN
open cur for 'with t1 as (select :A col from dual),
t2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col
from t1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null)
select col as id from t2' using A;
END;
/
Das Verfahren ist vereinfacht, soll aber ein Gefühl für die Handhabung vermitteln.
Der große Vorteil gegenüber der Verwendung von dynamischem SQL (Verkettung von Zeichenfolgen) besteht darin, dass Sie die Anweisung nicht bei jeder Ausführung analysieren müssen. Ganz zu schweigen von der Sicherheit (Angst vor SQL-Injection).
Verwendung:
DECLARE
l_cur SYS_REFCURSOR;
l_id NUMBER;
BEGIN
p_getdata('1,1000,282828,4',l_cur);
LOOP
FETCH l_cur INTO l_id ;
EXIT WHEN l_cur%NOTFOUND;
dbms_output.put_line(l_id);
END LOOP;
END;
/
1
1000
282828
4
AKTUALISIEREN
Das obige Verfahren ist vereinfacht, um Ihre Funktionalität zu erhalten, sollten Sie eine Abfrage wie diese im CURSOR verwenden (d. h. zuerst alle drei Parameter in separate Unterabfragen mit Unterabfrage-Factoring aufteilen, dann die Ergebnisse in Ihrer Abfrage anwenden)
CREATE or REPLACE PROCEDURE p_getdata(A IN VARCHAR2, B in VARCHAR2, c in VARCHAR2, cur OUT sys_refcursor)
AS
BEGIN
open cur for 'with ta1 as (select :A col from dual),
ta2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col
from ta1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null),
tb1 as (select :B col from dual),
tb2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col
from tb1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null),
tc1 as (select :C col from dual),
tc2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col
from tc1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null)
select firstname, lastname, streetname, city
from mytable
where zip IN (select col from ta2) AND
streetnumber IN (select col from tb2) AND
apt_num in (select col from tc2)' using A, B, C;
END;
/
Prüfung bestanden
DECLARE
l_cur SYS_REFCURSOR;
l_firstname VARCHAR2(20);
l_lastname VARCHAR2(20);
l_streetname VARCHAR2(20);
l_city VARCHAR2(20);
BEGIN
p_getdata('1100,,1200','1,2','11,12' ,l_cur);
LOOP
FETCH l_cur INTO l_firstname, l_lastname, l_streetname, l_city;
EXIT WHEN l_cur%NOTFOUND;
dbms_output.put_line(l_firstname|| ' ' || l_lastname || ' ' || l_streetname || ' ' || l_city);
END LOOP;
END;
/