sql >> Databasteknik >  >> RDS >> Mysql

Oracle:Parameteriserad fråga med IN-sats returnerar nullvärde

Du kan skicka den kommaseparerade listan som en parameter (bindningsvariabel), men du är ansvarig för att analysera den i en underfråga. En lösning baserad på denna tråd använder 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;
/

Proceduren är förenklad, men bör ge en känsla av hur man använder den.

Den stora fördelen mot att använda dynamisk SQL (sammansättning av strängar) är att du inte behöver analysera satsen vid varje exekvering. För att inte tala om säkerheten (rädsla för SQL-injektion).

Användning:

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

UPPDATERA

Ovanstående procedur är förenklad, för att få din funktionalitet bör du använda en fråga som denna i CURSOR (dvs först dela upp alla tre parametrarna i separata underfrågor med hjälp av subquery factoring, sedan tillämpa resultaten i din fråga)

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

testet godkänt

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


  1. gruppera efter första och sista förekomsten

  2. oracle jdbc drivrutin version galenskap

  3. Oracle:exportera en tabell med blobs till en .sql-fil som kan importeras igen

  4. Köra SQL-databasunderhållsuppgifter med SQLCMD