web-dev-qa-db-ja.com

pl / sqlオブジェクト・タイプ「ORA-06530:初期化されていないコンポジットへの参照」エラー

私は次のようなタイプを持っています:

CREATE OR REPLACE TYPE tbusiness_inter_item_bag AS OBJECT (
   item_id              NUMBER,
   system_event_cd      VARCHAR2 (20),
   CONSTRUCTOR FUNCTION tbusiness_inter_item_bag RETURN SELF AS RESULT
);
CREATE OR REPLACE TYPE BODY tbusiness_inter_item_bag
AS
   CONSTRUCTOR FUNCTION tbusiness_inter_item_bag RETURN SELF AS RESULT
   AS
   BEGIN
      RETURN;
   END;
END;

次のスクリプトを実行すると、「初期化されていないコンポジットへの参照」エラーが発生しました。これは非常に適切です。

DECLARE
   item   tbusiness_inter_item_bag;
BEGIN
   item.system_event_cd := 'ABC';
END;

これも同じエラーを引き起こします:

item.item_id := 3;

しかし、オブジェクトタイプを次のように変更すると、次のようになります。

CREATE OR REPLACE TYPE tbusiness_inter_item_bag AS OBJECT (
   item_id              NUMBER(1),
   system_event_cd      VARCHAR2 (20),
   CONSTRUCTOR FUNCTION tbusiness_inter_item_bag RETURN SELF AS RESULT
);

その後、最後のステートメントでエラーが発生しなくなります(「アイテム」がまだ初期化されていない場合)。

item.item_id := 3;

同じORA-06530エラーが発生するべきではありませんか?

ps:Oracle Database 10g Enterprise Editionリリース10.2.0.4.0-64bi

13
mutoss

Oracle11gR1でも同じ動作を再現しました。私はあなたに同意します、これは些細なことではありますが、私にとってもバグのようです。

SQL> CREATE OR REPLACE TYPE tbusiness_inter_item_bag AS OBJECT (
  2     item_id              NUMBER(1),
  3     system_event_cd      VARCHAR2 (20),
  4     CONSTRUCTOR FUNCTION tbusiness_inter_item_bag RETURN SELF AS RESULT
  5  );
  6  /

Type created.

SQL> DECLARE
  2     item   tbusiness_inter_item_bag;
  3  BEGIN
  4     item.item_id := 1;
  5  END;
  6  /

PL/SQL procedure successfully completed.

SQL>

これはまだ失敗することに注意してください:

SQL> DECLARE
  2     item   tbusiness_inter_item_bag;
  3  BEGIN
  4     item.item_id := 1;
  5     item.system_event_cd := 'ABC';
  6  END;
  7  /
DECLARE
*
ERROR at line 1:
ORA-06530: Reference to uninitialized composite
ORA-06512: at line 5

SQL>

明らかに、正しい方法は、オブジェクトを参照する前に常にオブジェクトを初期化することです。

SQL> DECLARE
  2     item   tbusiness_inter_item_bag := tbusiness_inter_item_bag();
  3  BEGIN
  4     item.system_event_cd  := 'ABC';
  5  END;
  6  /

PL/SQL procedure successfully completed.

SQL>
12
APC

定義したコンストラクターを呼び出す必要があります。

SQL> DECLARE
  2     item   tbusiness_inter_item_bag := tbusiness_inter_item_bag();
  3     /*                                 ^^ call the constructor */
  4  BEGIN
  5     item.system_event_cd := 'ABC';
  6  END;
  7  /

PL/SQL procedure successfully completed

10.2.0.3データベースで説明した動作を観察します。私はそれに依存しませんが、それはバグのように見えます。

0
Vincent Malgrat