sql >> Databasteknik >  >> RDS >> Oracle

Hur använder man parametrar i en "where value in..."-sats?

Att använda dynamisk SQL är den enklaste metoden ur kodningssynpunkt. Problemet med dynamisk SQL är dock att du måste analysera varje distinkt version av frågan som inte bara har potentialen att belasta din CPU utan har potentialen att översvämma din delade pool med massor av icke-delbara SQL-satser, tryckande ut uttalanden som du vill cachelagra, vilket orsakar fler hårda analyser och delade poolfragmenteringsfel. Om du kör detta en gång om dagen är det förmodligen inte ett större problem. Om hundratals människor utför det tusentals gånger om dagen är det förmodligen ett stort problem.

Ett exempel på den dynamiska SQL-metoden

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    l_deptnos  varchar2(100) := '10,20';
  3    l_rc       sys_refcursor;
  4    l_dept_rec dept%rowtype;
  5  begin
  6    open l_rc for 'select * from dept where deptno in (' || l_deptnos || ')';
  7    loop
  8      fetch l_rc into l_dept_rec;
  9      exit when l_rc%notfound;
 10      dbms_output.put_line( l_dept_rec.dname );
 11    end loop;
 12    close l_rc;
 13* end;
SQL> /
ACCOUNTING
RESEARCH

PL/SQL procedure successfully completed.

Alternativt kan du använda en samling. Detta har fördelen av att generera en enda, delbar markör så att du inte behöver oroa dig för hård analys eller översvämning av den delade poolen. Men det kräver nog lite mer kod. Det enklaste sättet att hantera samlingar

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    l_deptnos  tbl_deptnos := tbl_deptnos(10,20);
  3  begin
  4    for i in (select *
  5                from dept
  6               where deptno in (select column_value
  7                                  from table(l_deptnos)))
  8    loop
  9      dbms_output.put_line( i.dname );
 10    end loop;
 11* end;
SQL> /
ACCOUNTING
RESEARCH

PL/SQL procedure successfully completed.

Om du å andra sidan verkligen måste börja med en kommaseparerad lista med värden, måste du tolka den strängen till en samling innan du kan använda den. Det finns olika sätt att tolka en avgränsad sträng - min personliga favorit är att använda reguljära uttryck i en hierarkisk fråga, men du kan säkert också skriva ett procedurmässigt tillvägagångssätt

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    l_deptnos     tbl_deptnos;
  3    l_deptno_str  varchar2(100) := '10,20';
  4  begin
  5    select regexp_substr(l_deptno_str, '[^,]+', 1, LEVEL)
  6      bulk collect into l_deptnos
  7      from dual
  8   connect by level <= length(replace (l_deptno_str, ',', NULL));
  9    for i in (select *
 10                from dept
 11               where deptno in (select column_value
 12                                  from table(l_deptnos)))
 13    loop
 14      dbms_output.put_line( i.dname );
 15    end loop;
 16* end;
 17  /
ACCOUNTING
RESEARCH

PL/SQL procedure successfully completed.


  1. PostgreSQL Skapa index

  2. Hur byter man namn på uppladdad fil innan man sparar den i en katalog?

  3. Köra SQL Server 2014 på en Azure Virtual Machine

  4. anropa en lagrad proc över en dblink