2013-07-30 104 views
0

我想在Oracle對象類型中設置默認值,但它需要所有屬性都需要在構造函數中傳遞。在Oracle對象類型構造函數中設置默認值

無論如何,我只能在構造函數中傳遞需要默認值的必需屬性。

請看下面的詳細信息

 

    SQL> CREATE TYPE TYPE_SUB AS OBJECT(
     2 COL1 NUMBER, 
     3 COL2 VARCHAR2(100) 
     4 ) 
     5 NOT FINAL 
     6/

    Type created. 

    SQL> CREATE OR REPLACE TYPE 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) RETURN SELF AS RESULT) 
     7 NOT FINAL 
     8/

    Type created. 

    SQL> CREATE OR REPLACE TYPE BODY TYPE_MAIN IS 
     2 CONSTRUCTOR FUNCTION TYPE_MAIN (COL1 NUMBER, COL2 VARCHAR2, COL3 varchar2, COL4 VARCHAR2) RETURN SELF AS RESULT IS 
     3 BEGIN 
     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 end; 
    10 END; 
    11/

    Type body created. 

    SQL> CREATE TABLE TAB_MAIN (
     2 PKEY NUMBER, 
     3 COLTEST VARCHAR2(100), 
     4 COLNEW TYPE_MAIN) 
     5/

    Table created. 

    SQL> INSERT INTO TAB_MAIN(PKEY) VALUES(1) 
     2/

    1 row created. 

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

    1 row created. 

    SQL> INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW) VALUES(1,'TESTCOL2',TYPE_MAIN('1',NULL,NULL,NULL)) 
     2/

    1 row created. 

    SQL> SELECT * FROM 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 NOT FINAL 
     6/

    Type created. 

    SQL> CREATE OR REPLACE TYPE TYPE_MAIN 
     2 UNDER TYPE_SUB 
     3 (
     4 COL3 varchar2(10), 
     5 COL4 VARCHAR2(10), 
     6 CONSTRUCTOR FUNCTION TYPE_MAIN(COL3 varchar2, COL4 VARCHAR2) RETURN SELF AS RESULT) 
     7 NOT FINAL 
     8/

    Type created. 

    SQL> CREATE OR REPLACE TYPE BODY TYPE_MAIN IS 
     2 CONSTRUCTOR FUNCTION TYPE_MAIN (COL3 varchar2, COL4 VARCHAR2) RETURN SELF AS RESULT IS 
     3 BEGIN 
     4 SELF.COL3 := nvl(COL3,'NA'); 
     5 SELF.COL4 := nvl(COL4,NULL); 
     6 RETURN; 
     7 end; 
     8 END; 
     9/

    Type body created. 

    SQL> CREATE TABLE TAB_MAIN (
     2 PKEY NUMBER, 
     3 COLTEST VARCHAR2(100), 
     4 COLNEW TYPE_MAIN) 
     5/

    Table created. 

    SQL> INSERT INTO TAB_MAIN(PKEY) VALUES(1) 
     2/

    1 row created. 

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

    1 row created. 

    SQL> INSERT INTO TAB_MAIN(PKEY,COLTEST,COLNEW) VALUES(1,'TESTCOL2',TYPE_MAIN('1',NULL,NULL,NULL)) 
     2/

    1 row created. 

    SQL> SELECT * FROM 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) 

回答

3

在你的第二個代碼塊中,你沒有調用只有兩個參數的構造函數。傳遞一個空參數並不意味着你使用其他構造函數,而是用四個參數調用(默認)構造函數,其中兩個恰好爲空。你切實做好:

TYPE_MAIN(col1 => '1', col2 => NULL, col3 => NULL, col4 => NULL) 

TYPE_MAIN(col3 => '1', col4 => NULL) 

所以此工程:

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')   

要得到默認的工作,因爲我覺得你在你的第一個代碼塊打算,設置它們在構造函數參數中,而不在構造函數的主體中:

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; 
/

然後當只傳遞一個參數(或者任何時候你沒有通過它們全部,或者你想要從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')   

要同時通過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')   
+0

感謝名單亞歷克斯給了快速回復.... – user1017936