Oracle
 sql >> база данни >  >> RDS >> Oracle

Как да използвам параметри в клауза 'where value in...'?

Използването на динамичен SQL е най-простият подход от гледна точка на кодирането. Проблемът с динамичния SQL обаче е, че трябва да анализирате трудно всяка отделна версия на заявката, която не само има потенциала да натовари вашия процесор, но има потенциала да наводни вашия споделен пул с много SQL изрази, които не могат да се споделят, натискайки out изрази, които искате да кеширате, което води до по-трудни анализи и грешки при фрагментиране на споделен пул. Ако изпълнявате това веднъж на ден, това вероятно не е сериозно притеснение. Ако стотици хора го изпълняват хиляди пъти на ден, това вероятно е голямо притеснение.

Пример за динамичен SQL подход

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.

Като алтернатива можете да използвате колекция. Това има предимството да генерира един единствен курсор, който може да се споделя, така че не е нужно да се притеснявате за тежък анализ или наводняване на споделения пул. Но вероятно изисква малко повече код. Най-простият начин за работа с колекции

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.

Ако, от друга страна, наистина трябва да започнете със списък със стойности, разделени със запетая, тогава ще трябва да анализирате този низ в колекция, преди да можете да го използвате. Има различни начини за анализиране на разделен низ – моят личен фаворит е да използвам регулярни изрази в йерархична заявка, но със сигурност бихте могли да напишете и процедурен подход

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да конфигурирате Glassfish Server в Eclipse ръчно

  2. Какво означава знак (+) в клауза WHERE на Oracle SQL?

  3. Издаден SQL Developer 4.1.3

  4. Oracle:SQL заявка, която връща редове само с числови стойности

  5. Можем ли да актуализираме стойностите на първичния ключ на таблица?