【问题标题】:Oracle: specifying default value for object type columnOracle:为对象类型列指定默认值
【发布时间】:2012-04-13 03:16:43
【问题描述】:

我有一个没有参数构造函数的对象类型,但是当我将它指定为该类型列的默认值时,我得到 ORA-00904: invalid identifier error。

例子:

创建或替换类型 test_t 作为对象 ( 验证号码(10), 构造函数 test_t 返回 self 作为结果 ) 创建或替换类型主体 test_t AS 构造函数 test_t 按结果返回自我 开始 值:= 1; 返回; 结尾; 结尾; 创建表 test_table ( test_attr test_t 默认新 test_t() ) 错误:ORA-00904:“INKA”。“TEST_T”。“TEST_T”:标识符无效

如果我将 DEFAULT 替换为例如test_t(1),它可以工作,但是那种破坏了 OO 封装范式,我希望所有相同类型的字段都具有相同的默认“默认值”(希望你知道我的意思 :-)

我在这里遗漏了什么,或者这是正常的,不能使用这样的非默认构造函数?

【问题讨论】:

    标签: sql oracle object plsql oracle11g


    【解决方案1】:

    看起来这是不可能的。

    一种解决方法是使用触发器:

    CREATE OR REPLACE TRIGGER test_trigger
      BEFORE INSERT OR UPDATE
    ON test_table
      FOR EACH ROW
    WHEN ( new.test_attr IS NULL )
    BEGIN
      :new.test_attr := NEW test_t();
    END test_trigger;
    /
    

    顺便也没有完全忽略非默认构造函数,覆盖默认构造函数

    CONSTRUCTOR FUNCTION test_t(in_val NUMBER)
    RETURN SELF AS RESULT
    

    尝试使用DEFAULT NEW test_t(1) 定义表时导致异常:

    ORA-06553:PLS-307:与此调用匹配的“TEST_T”声明过多

    【讨论】:

    • ORA-06553:PLS-307 是重复构造函数定义的结果,Oracle 在这方面有点好笑;如果将“in_val”参数名称替换为 val(属性名称也是如此),它将正确覆盖默认构造函数。
    • 我知道触发器的解决方法,但是 5-10 行代码应该可以以更易读和更易于管理的方式实现。最初我认为这是不可能的,因为 SQL 上下文在 PL/SQL 上下文中看不到,但显然情况并非如此,因为那时没有任何 OO 东西可以在纯 SQL 中工作。所以这个问题要么是 Oracle 的疏忽,要么是我不知道的一些语法......
    • 我完全同意,我也不想在我的代码中使用触发器解决方法。顺便说一句,当使用val 覆盖构造函数时,使用ORA-00904: "KLASSX"."TEST_T"."TEST_T": invalid identifier 创建具有默认值的表已经失败。
    • 是的,它只是指出不能在默认子句中使用任何非默认构造函数,即使它是被覆盖的默认构造函数。如果几天之内没有人提出任何建议,我会接受您的回答并联系 Oracle(尽可能好)。
    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2019-12-18
    相关资源
    最近更新 更多