sql >> Database teknologi >  >> RDS >> Oracle

Hvordan bruger man parametre i en 'where value in...'-sætning?

Brug af dynamisk SQL er den enkleste tilgang fra et kodningssynspunkt. Problemet med dynamisk SQL er dog, at du er nødt til hårdt at analysere hver enkelt version af forespørgslen, som ikke kun har potentialet til at beskatte din CPU, men har potentialet til at oversvømme din delte pulje med masser af ikke-delbare SQL-sætninger, og skubbe udsagn, du gerne vil cache, hvilket forårsager flere hårde parses og delte poolfragmenteringsfejl. Hvis du kører dette en gang om dagen, er det sandsynligvis ikke en større bekymring. Hvis hundredvis af mennesker udfører det tusindvis af gange om dagen, er det sandsynligvis en stor bekymring.

Et eksempel på den dynamiske SQL-tilgang

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 bruge en samling. Dette har den fordel, at det genererer en enkelt, delbar markør, så du ikke behøver at bekymre dig om hård parsing eller oversvømmelse af den delte pulje. Men det kræver nok lidt mere kode. Den nemmeste måde at håndtere samlinger på

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.

Hvis du derimod virkelig skal starte med en kommasepareret liste over værdier, så bliver du nødt til at parse den streng til en samling, før du kan bruge den. Der er forskellige måder at parse en afgrænset streng på - min personlige favorit er at bruge regulære udtryk i en hierarkisk forespørgsel, men du kan bestemt også skrive en proceduremæssig tilgang

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. VÆLG DISTINCT på én kolonne

  2. Brug af Microsoft Access med Power BI

  3. Forskellen mellem sprog sql og sprog plpgsql i PostgreSQL-funktioner

  4. Start af blogging til HTML5 og CSS3