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

Colección de Oracle en la cláusula where

No puede usar una colección declarada localmente en una cláusula SQL:

declare
    type i_name is table of nvarchar2(512);
    i_itemname i_name := i_name();
    c number;
begin
    select distinct owner bulk collect into i_itemname from all_objects;
    dbms_output.put_line(i_itemname.count);
    select count(*) into c
    from all_tables
    where owner in (select * from table(i_itemname));
    dbms_output.put_line(c);
end;
/

    where owner in (select * from table(i_itemname));
                                        *
ERROR at line 10:
ORA-06550: line 10, column 41:
PLS-00642: local collection types not allowed in SQL statements
ORA-06550: line 10, column 35:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 8, column 5:
PL/SQL: SQL Statement ignored

Pero puede hacerlo si se declara a nivel de esquema, esencialmente para que SQL conozca el tipo, no solo PL/SQL:

create type i_name is table of nvarchar2(512);
/

Type created.

declare
    i_itemname i_name := i_name();      
    c number;
begin 
    select distinct owner bulk collect into i_itemname from all_objects;
    dbms_output.put_line(i_itemname.count);
    select count(*) into c from all_tables
    where owner in (select * from table(i_itemname));
    dbms_output.put_line(c);
end;
/

No errors.
18
128

PL/SQL procedure successfully completed.

También puedes unirte a la table construir en lugar de usar una subconsulta:

...
    select count(*) into c
    from table(i_itemname) t
    join all_tables at on at.owner = t.column_value;
...

Sin embargo, no tengo muy claro lo que estás diciendo. (Si no está utilizando la colección para nada más, sería mejor que simplemente uniera los datos sin procesar, pero asumo que la colección está ahí por una razón).

Como @haki mencionó en los comentarios, también puedes hacer:

...
    select count(*) into c
    from all_tables
    where owner member of (i_itemname);
...

... siempre que i_name y la columna con la que está comparando son iguales escribir . En mi ejemplo, encuentra cero filas porque estoy tratando de comparar nvarchar2 con varchar2 , pero encontraría una coincidencia si se redefiniera i_name como varchar2(512) . En su caso, presumiblemente tab.col es nvarchar2 de todos modos.