Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak używać parametrów w klauzuli „where value in...”?

Korzystanie z dynamicznego SQL jest najprostszym podejściem z punktu widzenia kodowania. Problem z dynamicznym SQL polega jednak na tym, że musisz ciężko analizować każdą odrębną wersję zapytania, która nie tylko może obciążać Twój procesor, ale może również zalać pulę współdzieloną wieloma nieudostępnianymi instrukcjami SQL. out instrukcji, które chcesz buforować, powodując więcej twardych analiz i błędów fragmentacji puli współdzielonej. Jeśli uruchamiasz to raz dziennie, prawdopodobnie nie jest to poważny problem. Jeśli setki ludzi wykonują to tysiące razy dziennie, jest to prawdopodobnie poważny problem.

Przykład dynamicznego podejścia 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.

Alternatywnie możesz użyć kolekcji. Ma to tę zaletę, że generuje pojedynczy, współużytkowany kursor, dzięki czemu nie musisz się martwić trudną analizą lub zalaniem współdzielonej puli. Ale prawdopodobnie wymaga to trochę więcej kodu. Najprostszy sposób radzenia sobie z kolekcjami

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.

Z drugiej strony, jeśli naprawdę musisz zacząć od listy wartości oddzielonych przecinkami, będziesz musiał przeanalizować ten ciąg w kolekcję, zanim będziesz mógł go użyć. Istnieją różne sposoby analizowania rozdzielanego ciągu — moim osobistym ulubionym jest używanie wyrażeń regularnych w zapytaniach hierarchicznych, ale z pewnością można też napisać podejście proceduralne

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. Jak stworzyć procedurę w Oracle SQL Developer?

  2. Jak sprawdzić NLS_LANG klienta?

  3. Uzyskanie wyjątku ORA-00942:tabela lub widok nie istnieje - podczas wstawiania do istniejącej tabeli

  4. Domyślny format daty Oracle to RRRR-MM-DD, DLACZEGO?

  5. Błąd SQL ORA-01722:nieprawidłowy numer