8

テーブル変数がないため(MS SQL Serverのように)、Oracleコードブロックでコレクションを使用しています。

DECLARE
    TYPE I_NAME IS TABLE OF NVARCHAR2(512);     
    I_ITEMNAME      I_NAME := I_NAME(); 
BEGIN 

コレクションを埋めるために「BULK COLLECT INTO I_ITEMNAME」を使用しています。
このコレクションを SELECT クエリの WHERE 句で使用したいのですが、それを行う方法が見つかりません。現在、私はFORループを使用してアイテムを1つずつ取得しています。
コレクションをWHERE句で直接使用するにはどうすればよいですか

SELECT * FROM TBL I_ITEMNAME の列は?

ありがとうございました、

4

1 に答える 1

17

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

ただし、スキーマ レベルで宣言されている場合は、基本的に SQL が 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.

tableサブクエリを使用する代わりに、構造を結合することもできます。

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

私はあなたがドンであるかどうかはよくわかりません。(コレクションを他の目的で使用していない場合は、生データを結合するだけの方がよいでしょうが、コレクションには何らかの理由があると思います)。


@haki がコメントで述べたように、次のこともできます。

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

i_name...と比較している列が同じタイプである限り。私の例では、 と比較しようとしているためゼロ行nvarchar2が見つかりましたが、としてvarchar2再定義すると一致が見つかります。あなたの場合、おそらくとにかくです。i_namevarchar2(512)tab.colnvarchar2

于 2013-04-24T07:28:13.167 に答える