參考分割槽子表使用GET_DEPENDENT_DDL結果異常

yangtingkun發表於2007-10-14

在11g中對於參考分割槽子表使用DBMS_METADATA.GET_DENPENDENT_DDL函式獲取外來鍵資訊時得到結果:begin NULL; end;


首先重現一下問題:

SQL> CREATE TABLE T_P (ID NUMBER PRIMARY KEY) PARTITION BY HASH (ID) PARTITIONS 4;

表已建立。

SQL> CREATE TABLE T_F (ID NUMBER, FID NUMBER NOT NULL,
2 CONSTRAINT FK_T_F FOREIGN KEY (FID) REFERENCES T_P)
3 PARTITION BY REFERENCE (FK_T_F);

表已建立。

SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'T_P') FROM DUAL;

DBMS_METADATA.GET_DDL('TABLE','T_P')
--------------------------------------------------------------------------------

CREATE TABLE "YANGTK"."T_P"
( "ID" NUMBER,
PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "YANGTK" ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "YANGTK"
PARTITION BY HASH ("ID")
(PARTITION "SYS_P81"
TABLESPACE "YANGTK",
PARTITION "SYS_P82"
TABLESPACE "YANGTK",
PARTITION "SYS_P83"
TABLESPACE "YANGTK",
PARTITION "SYS_P84"
TABLESPACE "YANGTK")

SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'T_F') FROM DUAL;

DBMS_METADATA.GET_DDL('TABLE','T_F')
--------------------------------------------------------------------------------

CREATE TABLE "YANGTK"."T_F"
( "ID" NUMBER,
"FID" NUMBER NOT NULL ENABLE,
CONSTRAINT "FK_T_F" FOREIGN KEY ("FID")
REFERENCES "YANGTK"."T_P" ("ID") ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
PARTITION BY REFERENCE ("FK_T_F")
(PARTITION "SYS_P85"
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "YANGTK" NOCOMPRESS ,
PARTITION "SYS_P86"
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "YANGTK" NOCOMPRESS ,
PARTITION "SYS_P87"
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "YANGTK" NOCOMPRESS ,
PARTITION "SYS_P88"
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "YANGTK" NOCOMPRESS )

首先建立一個簡單的分割槽參考的例子,對於子表,使用DBMS_METADATA.GET_DDL是可以正確獲取表資訊和參考資訊的,但是如果使用GET_DEPENDENT_DDL會得到:

SQL> SELECT DBMS_METADATA.GET_DEPENDENT_DDL('REF_CONSTRAINT', 'T_F') FROM DUAL;

DBMS_METADATA.GET_DEPENDENT_DDL('REF_CONSTRAINT','T_F')
--------------------------------------------------------------------------------

begin NULL; end;

剛開始認為是Oraclebug,認為GET_DEPENDENT_DDL函式處理參考約束時出現異常。後來仔細看了一下Oracle的文件關於參考分割槽的描述,發現這裡並非是bug

首先,由於參考分割槽表是利用參考約束建立起來的,因此分割槽表建立之後,參考約束是不能刪除或DISABLE的。

第二,由於只能在建表的時候建立成分割槽表,而不能透過ALTER TABLE將非分割槽錶轉化為分割槽表。這就意味著外來鍵約束也必須在建表的時候指定,而不能透過ALTER TABLE ADD CONSTRAINT的方式新增。

有了上面兩點限制,就意味著參考分割槽表的外來鍵不能透過ALTER TABLE的方式生成,而只能透過CREATE TABLE的時候指定。因此GET_DDL的結果中,CREATE TABLE語句包含了約束的建立。

既然不能透過ALTER TABLE來新增刪除,那麼GET_DEPENDENT_DDL給出ALTER TABLE ADD CONSTRAINT的結果就沒有意義,不但沒有意義,而且會產生誤導資訊。而這裡返回空也是有問題的,因為約束本身是存在的,返回空的話,和約束不存在無法區分。所以Oracle這裡選擇返回了BEGIN NULL; END;。看來Oracle在這裡還是經過仔細的考慮的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-69458/,如需轉載,請註明出處,否則將追究法律責任。

相關文章