sql >> Database >  >> RDS >> Oracle

Oracle-verzameling in waar-clausule

U kunt een lokaal gedeclareerde verzameling niet gebruiken in een SQL-clausule:

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

Maar dat kan als het op schemaniveau wordt gedeclareerd, in wezen zodat SQL het type kent, niet alleen 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.

U kunt ook deelnemen aan de table construeren in plaats van een subquery te gebruiken:

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

Het is me echter niet helemaal duidelijk wat je dong bent. (Als je de verzameling niet voor iets anders gebruikt, kun je beter gewoon de onbewerkte gegevens toevoegen, maar ik neem aan dat de verzameling er met een reden is).

Zoals @haki vermeldde in opmerkingen, kun je ook het volgende doen:

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

... zolang i_name en de kolom waarmee u vergelijkt zijn hetzelfde typ . In mijn voorbeeld vindt het nul rijen omdat ik nvarchar2 . probeer te vergelijken met varchar2 , maar zou een overeenkomst vinden als i_name opnieuw werd gedefinieerd als varchar2(512) . In jouw geval vermoedelijk tab.col is nvarchar2 hoe dan ook.




  1. Query invoegen in SQL-functie

  2. snelle selectie van een willekeurige rij uit een grote tabel in mysql

  3. DROP TABLE-instructie in SQL Server begrijpen

  4. postgresql zelf lid worden