sql >> Databáze >  >> RDS >> Oracle

Kolekce Oracle v klauzuli where

V klauzuli SQL nemůžete použít lokálně deklarovanou kolekci:

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

Ale můžete, pokud je deklarován na úrovni schématu, v podstatě tak, aby SQL věděl o typu, nejen 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.

Můžete se také připojit k table konstruovat spíše než používat poddotaz:

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

Není mi ale úplně jasné, co děláš. (Pokud sbírku nepoužíváte k ničemu jinému, bylo by lepší připojit se k nezpracovaným datům, ale předpokládám, že kolekce existuje z nějakého důvodu).

Jak @haki zmínil v komentářích, můžete také:

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

... pokud i_name a sloupec, který porovnáváte s jsou stejné typ . V mém příkladu najde nula řádků, protože se snažím porovnat nvarchar2 s varchar2 , ale najde shodu, pokud předefinujete i_name jako varchar2(512) . Ve vašem případě pravděpodobně tab.col je nvarchar2 každopádně.




  1. Zdroj dat odmítl navázání spojení, zpráva ze serveru:Příliš mnoho spojení

  2. Auto-inkrement MySQL mezi tabulkami

  3. PDO::bindParam ve smyčce foreach, všechny hodnoty jsou nastaveny jako stejné?

  4. jak vrátit dynamickou sadu výsledků ve funkci Oracle