在Oracle对象类型构造函数中设置默认值

use*_*936 1 oracle types plsql function object-type

我想在Oracle对象类型中设置默认值,但是它需要为此在构造函数中传递所有属性。

无论如何,有没有,所以我只能在需要默认值的构造函数中传递必需的属性。

请查看以下详细信息

    SQL> CREATE TYPE TYPE_SUB AS OBJECT(
      2 COL1 NUMBER,
      3个COL2 VARCHAR2(100)
      4)
      5非决赛
      6 /

    类型已创建。

    SQL>创建或替换类型TYPE_MAIN
      2 UNDER TYPE_SUB
      3(
      4个COL3 varchar2(10),
      5个COL4 VARCHAR2(10),
      6 CONSTRUCTOR FUNCTION TYPE_MAIN(COL1 NUMBER,COL2 VARCHAR2,COL3 varchar2,COL4 VARCHAR2)作为结果返回
      7非决赛
      8 /

    类型已创建。

    SQL>创建或替换类型主体TYPE_MAIN IS
      2构造函数函数_MAIN(COL1编号,COL2 VARCHAR2,COL3 varchar2,COL4 VARCHAR2)按结果返回自
      3开始
      4 SELF.COL1:= nvl(COL1,123);
      5 SELF.COL2:= nvl(COL2,'NA');
      6 SELF.COL3:= nvl(COL3,'NA');
      7 SELF.COL4:= nvl(COL4,NULL);
      8 RETURN;
      9结束;
     10 END;
     11 /

    输入创建的正文。

    SQL>创建表TAB_MAIN(
      2个PKEY NUMBER,
      3 COLTEST VARCHAR2(100),
      4个COLNEW TYPE_MAIN)
      5 /

    表已创建。

    SQL>插入TAB_MAIN(PKEY)值(1)
      2 /

    已创建1行。

    SQL>插入TAB_MAIN(PKEY,COLTEST,COLNEW)值(1,'TESTCOL',TYPE_MAIN('1','2',NULL,NULL))
      2 /

    已创建1行。

    SQL>插入TAB_MAIN(PKEY,COLTEST,COLNEW)值(1,'TESTCOL2',TYPE_MAIN('1',NULL,NULL,NULL))
      2 /

    已创建1行。

    SQL> SELECT *从TAB_MAIN
      2 /

          PKEY COLTEST COLNEW(COL1,COL2,COL3,COL4)
    ---------- ---------- ------------------------------ ----------
             1个
             1 TESTCOL TYPE_MAIN(1,'2','NA',NULL)
             1 TESTCOL2 TYPE_MAIN(1,'NA','NA',NULL)

现在,在上面的示例中,如果我仅在构造函数中传递Col3和Col4属性作为默认值,则此方法无效。请参见以下示例。

    SQL> CREATE TYPE TYPE_SUB AS OBJECT(
      2 COL1 NUMBER,
      3个COL2 VARCHAR2(100)
      4)
      5非决赛
      6 /

    类型已创建。

    SQL>创建或替换类型TYPE_MAIN
      2 UNDER TYPE_SUB
      3(
      4个COL3 varchar2(10),
      5个COL4 VARCHAR2(10),
      6 CONSTRUCTOR FUNCTION TYPE_MAIN(COL3 varchar2,COL4 VARCHAR2)作为结果返回自身)
      7非决赛
      8 /

    类型已创建。

    SQL>创建或替换类型主体TYPE_MAIN IS
      2 CONSTRUCTOR FUNCTION TYPE_MAIN(COL3 varchar2,COL4 VARCHAR2)根据结果返回自
      3开始
      4 SELF.COL3:= nvl(COL3,'NA');
      5 SELF.COL4:= nvl(COL4,NULL);
      6返回;
      7结束;
      8 END;
      9 /

    输入创建的正文。

    SQL>创建表TAB_MAIN(
      2个PKEY NUMBER,
      3 COLTEST VARCHAR2(100),
      4个COLNEW TYPE_MAIN)
      5 /

    表已创建。

    SQL>插入TAB_MAIN(PKEY)值(1)
      2 /

    已创建1行。

    SQL>插入TAB_MAIN(PKEY,COLTEST,COLNEW)值(1,'TESTCOL',TYPE_MAIN('1','2',NULL,NULL))
      2 /

    已创建1行。

    SQL>插入TAB_MAIN(PKEY,COLTEST,COLNEW)值(1,'TESTCOL2',TYPE_MAIN('1',NULL,NULL,NULL))
      2 /

    已创建1行。

    SQL> SELECT *从TAB_MAIN
      2 /

          PKEY COLTEST COLNEW(COL1,COL2,COL3,COL4)
    ---------- ---------- ------------------------------ ----------
             1个
             1个TESTCOL TYPE_MAIN(1,'2',NULL,NULL)
             1 TESTCOL2 TYPE_MAIN(1,NULL,NULL,NULL)

Ale*_*ole 5

在第二个代码块中,您不会调用仅具有两个参数的构造函数。传递null参数并不意味着您使用其他构造函数,而是使用四个参数调用(默认)构造函数,其中两个恰好是故意为null的。您实际上正在做:

TYPE_MAIN(col1 => '1', col2 => NULL, col3 => NULL, col4 => NULL)
Run Code Online (Sandbox Code Playgroud)

TYPE_MAIN(col3 => '1', col4 => NULL)
Run Code Online (Sandbox Code Playgroud)

所以这工作:

INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW) VALUES(1,'TESTCOL2',TYPE_MAIN('3','4'))
/

...

      PKEY COLTEST         COLNEW                                           
---------- --------------- --------------------------------------------------
         1                                                                    
         1 TESTCOL         TYPE_MAIN(1,'2',NULL,NULL)           
         1 TESTCOL2        TYPE_MAIN(1,NULL,NULL,NULL)          
         1 TESTCOL2        TYPE_MAIN(NULL,NULL,'3','4')         
Run Code Online (Sandbox Code Playgroud)

为了使默认值能够按照我想的那样在您的第一个代码块中工作,请在构造函数参数中而不是在构造函数的主体中进行设置:

CREATE OR REPLACE TYPE TYPE_MAIN
UNDER TYPE_SUB
(
COL3 varchar2(10),
COL4 VARCHAR2(10),
CONSTRUCTOR FUNCTION TYPE_MAIN(COL1 number default 123,
  COL2 VARCHAR2 default 'NA',
  COL3 varchar2 default 'NA',
  COL4 VARCHAR2 default null) RETURN SELF AS RESULT)
NOT FINAL
/

CREATE OR REPLACE TYPE BODY TYPE_MAIN  IS
CONSTRUCTOR FUNCTION TYPE_MAIN (COL1 number default 123,
  COL2 VARCHAR2 default 'NA',
  COL3 varchar2 default 'NA',
  COL4 VARCHAR2 default null) RETURN SELF AS RESULT IS
BEGIN
 SELF.COL1 := COL1;
 SELF.COL2 := COL2;
 SELF.COL3 := COL3;
 SELF.COL4 := COL4;
RETURN;
end;
END;
/
Run Code Online (Sandbox Code Playgroud)

然后,当仅传递一个参数(或任何时候不传递所有参数,或想要从顺序开始覆盖的前几个参数col1)时,您需要为其命名,而不是传递null其他参数,那样会仅覆盖默认值。

INSERT INTO TAB_MAIN(PKEY) VALUES(1)
/

INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW)
VALUES(1,'TESTCOL',TYPE_MAIN(1,'2'))
/

INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW)
VALUES(1,'TESTCOL2',TYPE_MAIN(1))
/

INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW)
VALUES(1,'TESTCOL3',TYPE_MAIN(col3 => '3'))
/

INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW)
VALUES(1,'TESTCOL4',TYPE_MAIN(col4 => '4'))
/

      PKEY COLTEST         COLNEW                                           
---------- --------------- --------------------------------------------------
         1                                                                    
         1 TESTCOL         TYPE_MAIN(1,'2','NA',NULL)           
         1 TESTCOL2        TYPE_MAIN(1,'NA','NA',NULL)          
         1 TESTCOL3        TYPE_MAIN(123,'NA','3',NULL)         
         1 TESTCOL4        TYPE_MAIN(123,'NA','NA','4')         
Run Code Online (Sandbox Code Playgroud)

要同时传递两者col3col4您仍然需要命名参数,否则将假定您从col1以下位置开始:

INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW)
VALUES(1,'TESTCOL5',TYPE_MAIN(col3 => '3', col4 => '4'))
/

      PKEY COLTEST         COLNEW                                           
---------- --------------- --------------------------------------------------
         1                                                                    
         1 TESTCOL         TYPE_MAIN(1,'2','NA',NULL)           
         1 TESTCOL2        TYPE_MAIN(1,'NA','NA',NULL)          
         1 TESTCOL3        TYPE_MAIN(123,'NA','3',NULL)         
         1 TESTCOL4        TYPE_MAIN(123,'NA','NA','4')         
         1 TESTCOL5        TYPE_MAIN(123,'NA','3','4')          
Run Code Online (Sandbox Code Playgroud)