sql >> Databáze >  >> RDS >> Oracle

Oracle - V otázce CLAUSE při použití s ​​více hodnotami, takže je dynamický

Bohužel, pokud je váš typ kolekce definován v PL/SQL (spíše než SQL), nemůžete jej použít v SQL, protože SQL engine neví, jak s ním zacházet.

Pokud jste místo toho definovali typ kolekce v SQL, tj.

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Pak můžete udělat něco jako

SELECT col1
  FROM table1 t1
 WHERE t1.id IN (SELECT column_value
                   FROM TABLE( <<variable of type varchar2_tbl>> ) )

v závislosti na verzi Oracle -- syntaxe pro použití kolekcí v SQL se postupem času vyvíjela -- starší verze Oracle měly složitější syntaxi.

Asociativní pole PL/SQL (vaše VARCHAR_ARRAY_TYPE) můžete převést na kolekci vnořených tabulek SQL v PL/SQL, ale to vyžaduje iteraci přes asociativní pole a naplnění vnořené tabulky, což je trochu bolestné. Za předpokladu, že VARCHAR_TBL kolekce vnořených tabulek již byla vytvořena

SQL> CREATE OR REPLACE TYPE varchar_tbl
         IS TABLE OF varchar2(40);

můžete převést z asociativního pole na vnořenou tabulku a použít vnořenou tabulku v příkazu SQL, jako je tento (pomocí tabulky SCOTT.EMP)

declare
  type varchar_array_type
    is table of varchar2(40)
       index by binary_integer;
  l_associative_array varchar_array_type;
  l_index             binary_integer;
  l_nested_table      varchar_tbl := new varchar_tbl();
  l_cnt               pls_integer;
begin
  l_associative_array( 1 ) := 'FORD';
  l_associative_array( 10 ) := 'JONES';
  l_associative_array( 100 ) := 'NOT A NAME';
  l_associative_array( 75 ) := 'SCOTT';
  l_index := l_associative_array.FIRST;
  while( l_index IS NOT NULL )
  loop
    l_nested_table.EXTEND;
    l_nested_table( l_nested_table.LAST ) :=
             l_associative_array( l_index );
    l_index := l_associative_array.NEXT( l_index );
  end loop;
  SELECT COUNT(*)
    INTO l_cnt
    FROM emp
   WHERE ename IN (SELECT column_value
                     FROM TABLE( l_nested_table ) );
  dbms_output.put_line( 'There are ' || l_cnt || ' employees with a matching name' );
end;

Protože však převod mezi typy kolekcí je trochu bolestivý, obecně by bylo lepší použít pouze kolekci vnořených tabulek (a předat ji uložené proceduře), pokud neexistuje konkrétní důvod, proč je asociativní pole potřeba.




  1. Priorita operátoru AND a OR ve výběrovém dotazu Mysql

  2. Jak mapovat typ Enum v mybatis pomocí typeHandler na insert

  3. Jak vytvořit databázové tabulky pomocí SQL

  4. Spojit – pole v tabulce 2 přepíší pole v tabulce 1