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

Oracle - Nella domanda CLAUSE quando si utilizza con più valori, rendendolo dinamico

Sfortunatamente, se il tuo tipo di raccolta è definito in PL/SQL (piuttosto che in SQL), non puoi usarlo in SQL perché il motore SQL non sa come gestirlo.

Se invece hai definito il tipo di raccolta in SQL, es.

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Quindi puoi fare qualcosa come

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

a seconda della versione di Oracle-- la sintassi per l'utilizzo delle raccolte in SQL si è evoluta nel tempo-- le versioni precedenti di Oracle avevano una sintassi più complessa.

Puoi convertire un array associativo PL/SQL (il tuo VARCHAR_ARRAY_TYPE) in una raccolta di tabelle nidificate SQL in PL/SQL, ma ciò richiede l'iterazione dell'array associativo e il riempimento della tabella nidificata, il che è un po' una seccatura. Supponendo che il VARCHAR_TBL la raccolta di tabelle nidificate è già stata creata

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

puoi convertire dall'array associativo alla tabella nidificata e utilizzare la tabella nidificata in un'istruzione SQL come questa (usando la tabella 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;

Poiché la conversione tra tipi di raccolta è un po' una seccatura, tuttavia, in genere è meglio utilizzare semplicemente la raccolta di tabelle nidificate (e passarla alla procedura memorizzata) a meno che non vi sia un motivo particolare per cui è necessario l'array associativo.