[解決済み] ORA-22905 - select 文でテーブルの種類を照会するとき。
質問事項
DECLARE
TYPE record_AB IS RECORD
(
AA VARCHAR2 (16 BYTE),
BB VARCHAR2 (16 BYTE)
);
TYPE type_tab_AB IS TABLE OF record_AB
INDEX BY BINARY_INTEGER;
tab_AB type_tab_AB;
BEGIN
SELECT *
BULK COLLECT INTO tab_AB FROM...
..
SELECT * FROM TABLE (tab_AB) ;
SELECT from TABLE ステートメントに到達すると、 "ORA-22905: cannot access rows from a non-nested table item" が表示されます。
PLSQLでテーブル型に問い合わせることは可能でしょうか?
どのように解決するのですか?
PL/SQLでテーブルの型を問い合わせることは可能ですが、スキーマレベル、つまりPL/SQLの外側で型が宣言されているネストされたテーブルと配列に限られます。
エラーについて
<ブロッククオートORA-22905: 入れ子になっていないテーブル項目から行にアクセスできない
は、サポートされていないテーブル型からクエリを実行しようとしていることを意味します。 あなたのタイプ
type_tab_AB
は連想配列であるため
INDEX BY BINARY_INTEGER
節があります。 を削除して
INDEX BY BINARY_INTEGER
節を使用することで
type_tab_AB
をネストされたテーブルタイプにすることです。 (配列もここで動作しますが、予想される行数の上限がわかっていない限り、使用することはお勧めしません。 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
NOTE 簡単のため、質問者はOracle11以前を使用していると仮定しています。 Oracle12では、PL/SQLで宣言された型をSQLクエリで使用することが認められていると思いますので、PLS-00642のエラーは発生しないかもしれません。 その他、Oracle12ではどのような変更が必要になるかは、Oracle12をまだ使用していないので何とも言えません。
関連
-
[解決済み】 "指定された集約関数を含まないクエリを実行しようとしました。"
-
[解決済み】一括読み込みデータ変換エラー(切り捨て)
-
[解決済み】SQL Serverは「集約関数やサブクエリを含む式に対して集約関数を実行できない」が、Sybaseはできる。
-
[解決済み] Varchar は Sum 演算子では無効です。
-
[解決済み] リンクされたサーバーの NULL に対して OLE DB プロバイダー Microsoft.Jet.OLEDB.4.0 のインスタンスを作成できません。
-
[解決済み] varchar 値の変換で int カラムがオーバーフローしました。
-
[解決済み] ORA-00918: 列があいまいに定義されています」を解決する方法
-
[解決済み] トリガーがコンパイルエラーで作成される
-
[解決済み] SQL ServerでJOINを使用してUPDATE文を実行するにはどうすればよいですか?
-
[解決済み】SQL Serverで既存のテーブルにデフォルト値を持つカラムを追加する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】参照するテーブルにプライマリーキーやキャンディデートキーがない
-
[解決済み】SQL ServerでIdentityカラムを更新する方法は?
-
[解決済み] テスト
-
[解決済み] INSERT ステートメントが FOREIGN KEY 制約と競合する - SQL Server
-
[解決済み] "このSqlTransactionは完了しました。もう使用できません。"...設定エラー?
-
[解決済み] 検索エラー ORA-00932: 不整合なデータ型: 期待された DATE は NUMBER になりました。
-
[解決済み] Presto の JSON_EXTRACT で ' ' 文字を含むキーに問題がある。
-
[解決済み] CLOBとNCLOBの違いは何ですか?
-
[解決済み] 1行目4列目(年)の一括読み込みデータ変換エラー(型の不一致または指定したコードページに対して無効な文字)
-
[解決済み] PLS-00428: この SELECT 文では INTO 句が必要です。