PL / SQLで表型を照会することは可能ですが、型がスキーマ・レベルで宣言されている、つまりPL/SQLの外部にあるネストされた表とVARRAYのみです。
エラー
ORA-22905:ネストされていない表項目の行にアクセスできません
サポートされていないテーブルタイプからクエリを実行しようとしていることを意味します。あなたのタイプtype_tab_AB
INDEX BY BINARY_INTEGER
のため、は連想配列です 句。 INDEX BY BINARY_INTEGER
を削除します type_tab_AB
を作成する句 ネストされたテーブルタイプ。 (Varrayもここで機能しますが、予想される行数の上限がわからない限り、Varrayを使用することはお勧めしません。VARRAYタイプを宣言するときは、要素の最大数を指定する必要がありますが、ネストされたテーブルタイプにはそのような制限はありません。)
この変更を行った後でも、コードが機能しない場合があります。次に発生する可能性のあるエラー(そうでない場合は下部の注を参照)は
PLS-00642:SQLステートメントで許可されていないローカルコレクションタイプ
これは、選択しているタイプがPL/SQL内で宣言されているためです。 type_tab_AB
を宣言する必要があります 、およびrecord_AB
PL / SQLの外部で、CREATE TYPE ...
を使用 。
次に発生する問題は、キーワードRECORD
が原因です。 。レコードタイプはPL/SQL内でのみ作成でき、スキーマレベルで作成することはできません。 RECORD
を変更します OBJECT
へ これを修正します。
発生する最後の問題は、SELECT t.AA, t.BB BULK COLLECT INTO tab_AB FROM ...
にあります。 声明。現状では、このクエリは次のエラーを出します:
PL / SQL:ORA-00947:値が不足しています
各行から2つのアイテムを選択し、データを一括挿入するためのテーブルを1つだけ提供しています。 Oracleは、2つのアイテムをrecord_AB
に詰め込みたいことを完全に理解できません。 タイプ。クエリをSELECT record_AB(t.AA, t.BB) BULK COLLECT INTO tab_AB FROM ...
に変更することで、これをかなり簡単に修正できます。 。
まとめると、これらの変更で問題が解決するはずです。これは、いくつかのテストデータを含むテストテーブルを作成し、テーブルタイプをクエリできることを確認する完全なSQL*Plusスクリプトです。
CREATE TABLE some_table (AA VARCHAR2(16 BYTE), BB VARCHAR2(16 BYTE));
INSERT INTO some_table (AA, BB) VALUES ('aa 1', 'bb 1');
INSERT INTO some_table (AA, BB) VALUES ('aaaaaaaaaa 2', 'b 2');
INSERT INTO some_table (AA, BB) VALUES ('aaaaa 3', 'bbbbbbbbbbbbbb 3');
COMMIT;
VARIABLE curs REFCURSOR;
CREATE OR REPLACE TYPE record_AB AS OBJECT
(
AA VARCHAR2 (16 BYTE),
BB VARCHAR2 (16 BYTE)
);
/
CREATE OR REPLACE TYPE type_tab_AB IS TABLE OF record_AB;
/
DECLARE
tab_AB type_tab_AB;
BEGIN
SELECT record_AB(t.AA, t.BB)
BULK COLLECT INTO tab_AB
FROM some_table t;
OPEN :curs FOR SELECT * FROM TABLE (tab_AB) ;
END;
/
PRINT :curs
SELECT
の結果を入れました tab_AB
の内容を確認する カーソルに挿入し、SQL*Plusカーソル変数を使用してその内容を一覧表示します。 Oracle 11g XEでスクリプトを実行したときに、「タイプが作成されました」および「PL/SQLプロシージャが正常に完了しました」というメッセージがすべて表示された後の出力は次のとおりです。
AA BB
---------------- ----------------
aa 1 bb 1
aaaaaaaaaa 2 b 2
aaaaa 3 bbbbbbbbbbbbbb 3
注: 簡単にするために、質問者はOracle11以前を使用していると仮定しました。 Oracle 12では、SQLクエリでPL / SQLで宣言された型を使用できると思います。そのため、PLS-00642エラーが発生しない可能性があります。 Oracle 12をまだ使用していないため、Oracle12で他にどのような変更が必要になるかはわかりません。