sql >> Base de Datos >  >> RDS >> Oracle

Oracle:en la pregunta CLÁUSULA cuando se usa con múltiples valores, haciéndolo dinámico

Desafortunadamente, si su tipo de colección está definido en PL/SQL (en lugar de SQL), no puede usarlo en SQL porque el motor SQL no sabe cómo manejarlo.

Si, en cambio, definió el tipo de colección en SQL, es decir,

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Entonces puedes hacer algo como

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

dependiendo de la versión de Oracle (la sintaxis para usar colecciones en SQL ha evolucionado con el tiempo), las versiones anteriores de Oracle tenían una sintaxis más compleja.

Puede convertir una matriz asociativa PL/SQL (su VARCHAR_ARRAY_TYPE) en una colección de tablas anidadas de SQL en PL/SQL, pero eso requiere iterar a través de la matriz asociativa y llenar la tabla anidada, lo cual es un poco molesto. Suponiendo que el VARCHAR_TBL la colección de tablas anidadas ya se ha creado

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

puede convertir de la matriz asociativa a la tabla anidada y usar la tabla anidada en una declaración SQL como esta (usando la tabla 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;

Debido a que la conversión entre tipos de colección es un poco complicada, sin embargo, generalmente sería mejor usar la colección de tablas anidadas (y pasarla al procedimiento almacenado) a menos que haya una razón particular por la que se necesita la matriz asociativa.