pl/sql 对象类型“ORA-06530:引用未初始化的复合”错误

Posted

技术标签:

【中文标题】pl/sql 对象类型“ORA-06530:引用未初始化的复合”错误【英文标题】:pl/sql object types "ORA-06530: Reference to uninitialized composite" error 【发布时间】:2010-06-11 09:34:13 【问题描述】:

我有一个类型如下:

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 数据库 10g 企业版版本 10.2.0.4.0 - 64bi

【问题讨论】:

【参考方案1】:

我在 Oracle 11gR1 中重现了相同的行为。我同意你的看法,这对我来说似乎也是一个错误,尽管是一个微不足道的错误。

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>

【讨论】:

确切答案,符合我的目的。谢谢【参考方案2】:

你需要调用你定义的构造函数:

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 数据库上描述的行为。不过我不会依赖它,它看起来像一个错误。

【讨论】:

文森特,我想你没抓住重点。对 item.item_id 的分配成功或失败取决于是否精确定义了数字属性。这种行为不一致,因此可能是一个错误。 @APC:是的,我已经意识到这是问题的对象。我更新了答案以反映我的观察结果(这看起来像一个错误:不要依赖它:) 是的,这对我来说也是一个错误,我只是想警告我的同事不要依赖它:) 我发布它是为了确定..【参考方案3】:

我不认为它的错误。根据文档,您应该初始化复合类型。这将始终有效: SQL> 声明 2 项 tbusiness_inter_item_bag := tbusiness_inter_item_bag(); 3 开始 4 item.system_event_cd := 'ABC'; 5 结束; 6 /

PL/SQL 过程成功完成。

SQL>

【讨论】:

以上是关于pl/sql 对象类型“ORA-06530:引用未初始化的复合”错误的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 私有对象方法

带有对象类型 PRIMARY KEY 的 PL/SQL

typeof 等价于 PL/SQL 中的对象类型

PL/SQL数据类型

PL/SQL的变量

如何在返回 SELF 的 pl/sql 对象类型的函数中链接调用