ORA-06530: Reference to uninitialized composite は、Oracle PL/SQLで初期化していないオブジェクト型や複合型を参照した時に発生するエラーです。特に、オブジェクト型の変数を宣言しただけで、コンストラクタを呼ばずに属性へ代入しようとした場合に起きやすいです。
Oracle公式のORA-06530説明では、object、LOB、その他のcompositeを初期化せずに左辺として参照したことが原因で、適切なコンストラクタまたはwhole-object assignmentで初期化することが対処として示されています。
ORA-06530が出たら、対象のオブジェクト変数を
type_name(...) のコンストラクタで初期化してから属性へ代入します。コレクション未初期化なら ORA-06531、発生行の追跡は ORA-06512 を確認します。ORA-06530とは
ORA-06530は、複合型の変数そのものがNULL状態のまま、属性や要素を更新しようとした時に出ます。単純な数値や文字列ではなく、オブジェクト型、LOB、複合型の初期化漏れを疑います。
| 対象 | 未初期化の例 | 起きやすいエラー |
|---|---|---|
| オブジェクト型 | l_order t_order_obj; のまま l_order.id := 1 |
ORA-06530 |
| コレクション | l_ids t_num_list; のまま l_ids.EXTEND |
ORA-06531 |
| 添字問題 | 初期化済みだが範囲外の添字を使う | ORA-06532 / ORA-06533 |
| 値や型の問題 | 属性へ長すぎる文字列や不正な数値を代入 | ORA-06502 |
発生する典型例
次の例では、オブジェクト型の変数 l_order を宣言しただけで、コンストラクタを呼んでいません。この状態で属性 order_id に代入しようとするとORA-06530になります。
CREATE OR REPLACE TYPE t_order_obj AS OBJECT ( order_id NUMBER, status VARCHAR2(20) ); / DECLARE l_order t_order_obj; BEGIN l_order.order_id := 1001; END; / -- ORA-06530: Reference to uninitialized composite -- ORA-06512: at line 4
ここでの問題は、order_id という属性ではなく、親である l_order そのものがNULL状態であることです。
基本の直し方
オブジェクト型は、型名と同じコンストラクタでインスタンスを作ってから属性を更新します。属性に初期値を入れたい場合も、まずオブジェクト全体を生成します。
DECLARE l_order t_order_obj := t_order_obj(NULL, NULL); BEGIN l_order.order_id := 1001; l_order.status := 'NEW'; DBMS_OUTPUT.PUT_LINE(l_order.order_id || ':' || l_order.status); END; /
| やりたいこと | 書き方 | 注意点 |
|---|---|---|
| 空に近い状態で作る | t_order_obj(NULL, NULL) |
オブジェクト自体は初期化済みになる |
| 初期値付きで作る | t_order_obj(1001, 'NEW') |
属性の順番と型を合わせる |
| あとから属性を更新する | コンストラクタ後に l_order.status := ... |
親オブジェクトがNULLでないこと |
| 全体を差し替える | l_order := t_order_obj(...) |
whole-object assignmentとして扱える |
症状別の最短修正
ORA-06530は、どの複合型がNULLのままなのかを見つけると早く直せます。発生行の左辺や戻り値を見て、次のように切り分けます。
| 症状 | 原因になりやすい箇所 | 最短修正 |
|---|---|---|
l_obj.attr := ...で失敗 |
親オブジェクトl_objがNULL |
l_obj := t_obj(...)で初期化 |
| 関数戻り値の属性参照で失敗 | 関数がNULLオブジェクトを返している | NULL判定するか初期化済みオブジェクトを返す |
| OUT引数を呼び出し元で使うと失敗 | プロシージャ内でOUTオブジェクトを初期化していない | OUT引数にコンストラクタ結果を代入 |
| 親は初期化済みなのに子で失敗 | 属性内のオブジェクトやコレクションがNULL | 子属性もコンストラクタで初期化 |
| 初期化後に別エラーになる | 属性値の型や長さが合っていない | ORA-06502として確認 |
whole-object assignmentで直す
属性を1つずつ代入する前に、オブジェクト全体を代入して初期化する方法もあります。Oracle公式の対処にもあるように、コンストラクタまたはwhole-object assignmentで複合型全体を初期化するのが基本です。
DECLARE l_order t_order_obj; BEGIN l_order := t_order_obj(1001, 'NEW'); l_order.status := 'CONFIRMED'; END; /
オブジェクト型の属性にコレクションがある場合
親オブジェクトを初期化していても、属性として持っているコレクションがNULLだと、別の未初期化エラーにつながります。親と子の両方を初期化する意識が必要です。
CREATE OR REPLACE TYPE t_num_list AS TABLE OF NUMBER; / CREATE OR REPLACE TYPE t_order_detail AS OBJECT ( order_id NUMBER, item_ids t_num_list ); / DECLARE l_order t_order_detail := t_order_detail(1001, NULL); BEGIN l_order.item_ids.EXTEND; END; / -- 親は初期化済みだが item_ids がNULL
DECLARE l_order t_order_detail := t_order_detail(1001, t_num_list()); BEGIN l_order.item_ids.EXTEND; l_order.item_ids(1) := 501; END; /
コレクション属性が未初期化の場合は、ORA-06531の原因と解決方法 の考え方がそのまま使えます。
ネストしたオブジェクト属性で起きる場合
親オブジェクトだけでなく、属性として持っている子オブジェクトも初期化が必要です。親を生成していても、子属性にNULLを渡していれば、子属性のさらに内側を更新する時にORA-06530になります。
CREATE OR REPLACE TYPE t_customer_obj AS OBJECT ( customer_id NUMBER, name VARCHAR2(100) ); / CREATE OR REPLACE TYPE t_order_with_customer AS OBJECT ( order_id NUMBER, customer t_customer_obj ); / DECLARE l_order t_order_with_customer := t_order_with_customer(1001, NULL); BEGIN l_order.customer.name := 'SATO'; END; / -- customer がNULLなので ORA-06530
DECLARE
l_order t_order_with_customer :=
t_order_with_customer(1001, t_customer_obj(NULL, NULL));
BEGIN
l_order.customer.customer_id := 501;
l_order.customer.name := 'SATO';
END;
/
レコード型との違い
PL/SQLの RECORD 変数は、オブジェクト型とは扱いが少し違います。通常のレコード変数は宣言すればフィールドに代入できますが、オブジェクト型はコンストラクタで生成する必要があります。この違いを混同するとORA-06530に気づきにくくなります。
DECLARE
TYPE t_order_rec IS RECORD (
order_id NUMBER,
status VARCHAR2(20)
);
l_order t_order_rec;
BEGIN
l_order.order_id := 1001;
l_order.status := 'NEW';
END;
/
-- RECORDはこの形で使える
PL/SQLの基本構文やブロックの考え方は PL/SQL基本構文完全ガイド も参考になります。
ORA-06531との違い
ORA-06530とORA-06531は、どちらも未初期化が原因ですが、対象が違います。何がNULL状態なのかを見ると切り分けやすいです。
| エラー | 対象 | 例 | 対処 |
|---|---|---|---|
ORA-06530 |
オブジェクト型、LOB、その他composite | l_obj.attr := ... |
コンストラクタまたは全体代入 |
ORA-06531 |
コレクション | l_list.EXTEND |
コレクションコンストラクタで初期化 |
ORA-06532 |
添字の許容範囲外 | l_list(0)、VARRAY上限超え |
添字値とLIMIT確認 |
ORA-06533 |
要素数超え | COUNT=0でl_list(1) |
EXTENDやCOUNT確認 |
関数戻り値やOUT引数で起きる場合
関数やプロシージャからオブジェクト型を返す時に、NULLのまま返すと呼び出し元でORA-06530になることがあります。0件や該当なしを表したい場合でも、呼び出し元が属性を参照するなら、NULLではなく初期化済みオブジェクトを返す設計にします。
CREATE OR REPLACE FUNCTION get_order RETURN t_order_obj IS l_order t_order_obj; BEGIN RETURN l_order; END; / -- 呼び出し元で result.status := ... のように使うとORA-06530になり得る
CREATE OR REPLACE FUNCTION get_order RETURN t_order_obj IS BEGIN RETURN t_order_obj(NULL, NULL); END; /
調査手順
実際にORA-06530が出たら、直後の ORA-06512 で発生行を確認し、USER_SOURCE で該当箇所を見ます。その行で属性代入しているオブジェクト変数が、直前でコンストラクタまたはwhole-object assignmentにより初期化されているかを見ます。
SELECT line,
text
FROM user_source
WHERE name = 'PKG_ORDER'
AND type = 'PACKAGE BODY'
AND line BETWEEN 80 AND 105
ORDER BY line;
発生行の読み方は ORA-06512の原因と読み方、バックトレースのログ設計は DBMS_UTILITY完全ガイド が参考になります。
| 順番 | 見る場所 | 確認内容 |
|---|---|---|
| 1 | ORA-06512の最初のオブジェクト付き行 | どの行で属性代入しているか |
| 2 | 属性の左側 | l_obj.attr の l_obj がNULLでないか |
| 3 | 直前の初期化 | コンストラクタまたは全体代入があるか |
| 4 | 戻り値・OUT引数 | NULLオブジェクトを受け取っていないか |
| 5 | 属性の型 | 属性がコレクションなら子も初期化しているか |
よくある原因と対処一覧
| 原因 | 症状 | 対処 |
|---|---|---|
| オブジェクト型を宣言しただけ | l_obj.attr := ...でORA-06530 |
先にtype_name(...)で初期化 |
| 関数がNULLオブジェクトを返す | 呼び出し元で属性参照時に失敗 | 初期化済みオブジェクトを返すかNULL判定する |
| OUT引数にNULLを返す | 呼び出し元で代入・参照時に失敗 | 呼び出し先でコンストラクタを代入 |
| 親だけ初期化して子属性がNULL | コレクション属性で失敗 | 子コレクションも初期化 |
| 値の代入先が合わない | 初期化後にORA-06502 | ORA-06502として型や桁を確認 |
チェックリスト
| 項目 | OKの状態 |
|---|---|
| オブジェクト変数を初期化した | type_name(...) を代入している |
| 属性代入前にNULLでない | 親オブジェクトが生成済み |
| 関数戻り値を確認した | NULLオブジェクトを返していない |
| OUT引数を確認した | 呼び出し元で使う前に初期化済み |
| 子コレクションも初期化した | 親だけでなく属性内の複合型も生成済み |
| ORA-06512の行を確認した | 発生行と呼び出し元を分けて読んでいる |
よくある質問
オブジェクト型を宣言しただけでは使えませんか?
属性参照や属性代入をするには、コンストラクタでオブジェクトを初期化する必要があります。
RECORD型でもORA-06530になりますか?
通常のPL/SQL RECORDは宣言後にフィールド代入できます。ORA-06530で多いのはオブジェクト型やその他の複合型の未初期化です。
ORA-06531とは何が違いますか?
ORA-06530はオブジェクト型などのcomposite、ORA-06531はコレクションの未初期化です。親オブジェクトかコレクションかを見ます。
NULLを返したい場合はどうすればよいですか?
呼び出し元でNULL判定してから属性参照します。呼び出し元が必ず属性を使う設計なら、NULLではなく初期化済みオブジェクトを返す方が安全です。
まとめ
ORA-06530は、初期化していないオブジェクト型や複合型を参照した時に発生します。属性へ代入する前に、type_name(...) のコンストラクタ、またはwhole-object assignmentでオブジェクト全体を初期化します。
コレクション未初期化のORA-06531とは対象が違いますが、どちらも「親となる変数がNULL状態のまま使われている」点は似ています。ORA-06512で発生行を確認し、左辺の親オブジェクトが初期化済みかを確認するのが最短です。
参考
ORA-06530 – Oracle Database Error Help
Object Methods – Oracle Database Object-Relational Developer's Guide
Using PL/SQL With Object Types – Oracle Database Object-Relational Developer's Guide
