Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle-Sammlung in der Where-Klausel

Sie können keine lokal deklarierte Sammlung in einer SQL-Klausel verwenden:

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

Aber Sie können, wenn es auf Schemaebene deklariert ist, im Wesentlichen damit SQL den Typ kennt, nicht nur 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.

Sie können auch am table teilnehmen eine Unterabfrage erstellen statt verwenden:

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

Ich bin nicht ganz klar, was du dong though. (Wenn Sie die Sammlung für nichts anderes verwenden, sollten Sie besser nur die Rohdaten zusammenführen, aber ich nehme an, dass die Sammlung aus einem bestimmten Grund vorhanden ist).

Wie @haki in den Kommentaren erwähnt hat, können Sie auch Folgendes tun:

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

... solange i_name und die Spalte, die Sie mit vergleichen, sind identisch Typ . In meinem Beispiel findet es null Zeilen, weil ich versuche, nvarchar2 zu vergleichen mit varchar2 , würde aber eine Übereinstimmung finden, wenn i_name neu definiert würde als varchar2(512) . In Ihrem Fall vermutlich tab.col ist nvarchar2 sowieso.