以前测试和使用的时候还真的没发现这个问题,一直认为COPY_TABLE_DEPENDENTS会自动过滤NOT NULL约束。
然而事实并发如此,如果打算使用COPY_TABLE_DEPENDENTS过程复制索引、约束以及权限等相关对象,那么在建立目标表的时候,即使是NOT NULL约束都应该避免,否则NOT NULL约束的存在会引发错误:
SQL> CREATE TABLE T AS
2 SELECT ROWNUM ID, OBJECT_NAME NAME, OBJECT_TYPE TYPE
3 FROM USER_OBJECTS A;
Table created.
SQL> ALTER TABLE T ADD PRIMARY KEY (ID);
Table altered.
SQL> ALTER TABLE T MODIFY NAME NOT NULL;
Table altered.
SQL> CREATE TABLE T_INTER
2 (ID NUMBER, NAME VARCHAR2(30) NOT NULL, TYPE VARCHAR2(30))
3 PARTITION BY HASH (ID)
4 PARTITIONS 4;
Table created.
SQL> SET SERVEROUT ON SIZE 1000000
SQL> BEGIN
2 DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> BEGIN
2 DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_INTER');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> VAR V_NUM NUMBER
SQL> BEGIN
2 DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(USER, 'T', 'T_INTER',
3 DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, FALSE, :V_NUM, TRUE);
4 END;
5 /
BEGIN
*
ERROR at line 1:
ORA-01442: column to be modified to NOT NULL is already NOT NULL
ORA-06512: at "SYS.DBMS_REDEFINITION", line 984
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1726
ORA-06512: at line 2
对于这种情况,除了避免在建表的时候指定NOT NULL之外,还可以通过指定COPY_TABLE_DEPENDENTS过程的IGNORE_ERRORS参数为TRUE的方式,来避免错误中止过程的执行。
SQL> BEGIN
2 DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(USER, 'T', 'T_INTER',
3 DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, :V_NUM, TRUE);
4 END;
5 /
PL/SQL procedure successfully completed.
SQL> PRINT V_NUM
V_NUM
----------
1
上面就忽略了NOT NULL约束引发的错误,从而完成了表的相关对象的复制过程,但是这种方法也存在问题,比如返回的错误数很多,就很难判断到底发生了哪些错误。这时不如让错误信息显示出来更直接一些。
即使COPY_TABLE_DEPENDENTS出现了错误也无所谓,可以检查目标表上的索引、约束、权限和触发器的情况,判断当前执行到哪一步报错。对于已经拷贝的对象,再次运行COPY_TABLE_DEPENDENTS过程时,将这种类型对应的参数置为FALSE即可。
SQL> BEGIN
2 DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_INTER');
3 END;
4 /
PL/SQL procedure successfully completed.
当所有依赖对象都成功的复制完成,可以执行FINISH_REDEF_TABLE过程来完成在线重定义的操作。
oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html