在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;
刚开始认为是Oracle的bug,认为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/,如需转载,请注明出处,否则将追究法律责任。