Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle - Na CLÁUSULA questão ao usar com vários valores, tornando-o dinâmico


Infelizmente, se seu tipo de coleção for definido em PL/SQL (em vez de SQL), você não poderá usá-lo em SQL porque o mecanismo SQL não sabe como lidar com isso.

Se, em vez disso, você definiu o tipo de coleção em SQL, ou seja,
CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Então você pode fazer algo como
SELECT col1
  FROM table1 t1
 WHERE t1.id IN (SELECT column_value
                   FROM TABLE( <<variable of type varchar2_tbl>> ) )

dependendo da versão do Oracle -- a sintaxe para usar coleções no SQL evoluiu com o tempo -- as versões mais antigas do Oracle tinham uma sintaxe mais complexa.

Você pode converter uma matriz associativa PL/SQL (seu VARCHAR_ARRAY_TYPE) em uma coleção de tabelas aninhadas SQL em PL/SQL, mas isso requer iteração pela matriz associativa e preenchimento da tabela aninhada, o que é um pouco trabalhoso. Supondo que o VARCHAR_TBL a coleção de tabelas aninhadas já foi criada
SQL> CREATE OR REPLACE TYPE varchar_tbl
         IS TABLE OF varchar2(40);

você pode converter da matriz associativa para a tabela aninhada e usar a tabela aninhada em uma instrução SQL como esta (usando a tabela 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;

Como a conversão entre tipos de coleção é um pouco trabalhosa, no entanto, geralmente seria melhor usar a coleção de tabelas aninhadas (e passá-la para o procedimento armazenado), a menos que haja um motivo específico pelo qual a matriz associativa seja necessária.