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

Coleção Oracle na cláusula where


Você não pode usar uma coleção declarada localmente em uma 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

Mas você pode se for declarado no nível do esquema, essencialmente para que o SQL saiba sobre o tipo, não apenas 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.

Você também pode participar da table construir em vez de usar uma subconsulta:
...
    select count(*) into c
    from table(i_itemname) t
    join all_tables at on at.owner = t.column_value;
...

Eu não estou muito claro o que você está fazendo embora. (Se você não estiver usando a coleção para mais nada, seria melhor apenas juntar os dados brutos, mas presumo que a coleção esteja lá por um motivo).

Como @haki mencionou nos comentários, você também pode fazer:
...
    select count(*) into c
    from all_tables
    where owner member of (i_itemname);
...

... contanto que i_name e a coluna que você está comparando com são iguais digite . No meu exemplo, ele encontra zero linhas porque estou tentando comparar nvarchar2 com varchar2 , mas encontraria uma correspondência se i_name redefinido como varchar2(512) . No seu caso, presumivelmente tab.col é nvarchar2 de qualquer forma.