10g的在线重定义解决这个问题。如果对象是利用COPY_TABLE_DEPENDENTS创建的,那么这些关联的对象在重定义操作完成后,自动改为原始的名称。如果是手工创建的关联对象,则可以利用REGISTER_DEPENDENT_OBJECT过程,所有执行了REGISTER_DEPENDENT_OBJECT过程的关联对象,都会在重定义操作完成后自动重命名。

这篇文章来看COPY_TABLE_DEPENDENTS的例子。



首先看看9i下的例子:

SQL> SELECT * FROM V$VERSION;


BANNER


----------------------------------------------------------------


Oracle9i Enterprise Edition Release9.2.0.4.0 -Production


PL/SQL Release 9.2.0.4.0 - Production


CORE    9.2.0.3.0       Production


TNS for 32-bit Windows: Version 9.2.0.4.0 - Production


NLSRTL Version 9.2.0.4.0 - Production


SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM USER_OBJECTS A;


表已创建。


SQL> ALTER TABLE T ADD CONSTRAINT PK_T PRIMARY KEY (ID);


表已更改。


SQL> ALTER TABLE T ADD CHECK (ID > 0);


表已更改。


SQL> CREATE INDEX IND_T_NAME ON T (OBJECT_NAME);


索引已创建。


SQL> CREATE OR REPLACE TRIGGER TRI_T


 2  BEFORE INSERT ON T


 3  FOR EACH ROW


 4  BEGIN


 5  NULL;


 6  END;


 7  /


触发器已创建


SQL> CREATE TABLE T_INTER


 2  PARTITION BY HASH (ID)


 3  PARTITIONS 4


 4  AS SELECT ROWNUM ID, A.*


 5  FROM USER_OBJECTS A


 6  WHERE 1 = 2;


表已创建。


SQL> ALTER TABLE T_INTER ADD CONSTRAINT PK_T_INTER PRIMARY KEY (ID);


表已更改。


SQL> ALTER TABLE T_INTER ADD CHECK (ID > 0) DISABLE;


表已更改。


SQL> CREATE INDEX IND_T_INTER_NAME ON T_INTER (OBJECT_NAME);


索引已创建。


SQL> CREATE OR REPLACE TRIGGER TRI_T_INTER


 2  BEFORE INSERT ON T_INTER


 3  FOR EACH ROW


 4  BEGIN


 5  NULL;


 6  END;


 7  /


触发器已创建


SQL> SET SERVEROUT ON SIZE 1000000


SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T')


PL/SQL过程已成功完成。


SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_INTER')


PL/SQL过程已成功完成。


SQL> SELECT TABLE_NAME, INDEX_NAME


 2  FROM USER_INDEXES


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     INDEX_NAME


------------------------------ ------------------------------


T_INTER                        IND_T_INTER_NAME


T                              IND_T_NAME


T                              PK_T


T_INTER                        PK_T_INTER


SQL> SELECT TABLE_NAME, CONSTRAINT_NAME


 2  FROM USER_CONSTRAINTS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     CONSTRAINT_NAME


------------------------------ ------------------------------


T                              PK_T


T                              SYS_C002990


T_INTER                        PK_T_INTER


T_INTER                        SYS_C002992


SQL> SELECT TABLE_NAME, TRIGGER_NAME


 2  FROM USER_TRIGGERS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     TRIGGER_NAME


------------------------------ ------------------------------


T                              TRI_T


T_INTER                        TRI_T_INTER


SQL> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_INTER')


PL/SQL过程已成功完成。


SQL> SELECT TABLE_NAME, INDEX_NAME


 2  FROM USER_INDEXES


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     INDEX_NAME


------------------------------ ------------------------------


T                              IND_T_INTER_NAME


T_INTER                        IND_T_NAME


T_INTER                        PK_T


T                              PK_T_INTER


SQL> SELECT TABLE_NAME, CONSTRAINT_NAME


 2  FROM USER_CONSTRAINTS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     CONSTRAINT_NAME


------------------------------ ------------------------------


T                              PK_T_INTER


T                              SYS_C002992


T_INTER                        PK_T


T_INTER                        SYS_C002990


SQL> SELECT TABLE_NAME, TRIGGER_NAME


 2  FROM USER_TRIGGERS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     TRIGGER_NAME


------------------------------ ------------------------------


T_INTER                        TRI_T


T                              TRI_T_INTER


SQL> DROP TABLE T_INTER;


表已删除。


可以看到,执行完重定义操作后,所有的关联对象的名称都与原来不一样了。

再看看10g使用COPY_TABLE_DEPENDENTS的例子,执行完在线重定义,新生成的表对应的这些对象的名称是否能与原表一致:

SQL> SELECT * FROM V$VERSION;


BANNER


----------------------------------------------------------------


Oracle Database10gEnterprise Edition Release10.2.0.1.0 - Prod


PL/SQL Release 10.2.0.1.0 - Production


CORE    10.2.0.1.0      Production


TNS for 32-bit Windows: Version 10.2.0.1.0 - Production


NLSRTL Version 10.2.0.1.0 - Production


SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM USER_OBJECTS A;


表已创建。


SQL> ALTER TABLE T ADD CONSTRAINT PK_T PRIMARY KEY (ID);


表已更改。


SQL> ALTER TABLE T ADD CHECK (ID > 0);


表已更改。


SQL> CREATE INDEX IND_T_NAME ON T (OBJECT_NAME);


索引已创建。


SQL> CREATE OR REPLACE TRIGGER TRI_T


 2  BEFORE INSERT ON T


 3  FOR EACH ROW


 4  BEGIN


 5  NULL;


 6  END;


 7  /


触发器已创建


SQL> CREATE TABLE T_INTER


 2  PARTITION BY HASH (ID)


 3  PARTITIONS 4


 4  AS SELECT ROWNUM ID, A.*


 5  FROM USER_OBJECTS A


 6  WHERE 1 = 2;


表已创建。


SQL> SET SERVEROUT ON SIZE 1000000


SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T')


PL/SQL过程已成功完成。


SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_INTER')


PL/SQL过程已成功完成。


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, TRUE, :V_NUM, TRUE);


 4  END;


 5  /


PL/SQL过程已成功完成。


SQL> PRINT V_NUM


    V_NUM


----------


        0


SQL> SELECT TABLE_NAME, INDEX_NAME


 2  FROM USER_INDEXES


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     INDEX_NAME


------------------------------ ------------------------------


T_INTER                        TMP$$_PK_T0


T_INTER                        TMP$$_IND_T_NAME0


T                              PK_T


T                              IND_T_NAME


SQL> SELECT TABLE_NAME, CONSTRAINT_NAME


 2  FROM USER_CONSTRAINTS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     CONSTRAINT_NAME


------------------------------ ------------------------------


T                              PK_T


T                              SYS_C0011881


T_INTER                        TMP$$_SYS_C00118810


T_INTER                        TMP$$_PK_T0


SQL> SELECT TABLE_NAME, TRIGGER_NAME


 2  FROM USER_TRIGGERS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     TRIGGER_NAME


------------------------------ ------------------------------


T                              TRI_T


T_INTER                        TMP$$_TRI_T0


SQL> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_INTER')


PL/SQL过程已成功完成。


在线重定义操作已经完成,再次检查表上的索引、约束和触发器的名称:

SQL> SELECT TABLE_NAME, INDEX_NAME


 2  FROM USER_INDEXES


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     INDEX_NAME


------------------------------ -------------------------


T                              PK_T


T                              IND_T_NAME


T_INTER                        TMP$$_PK_T0


T_INTER                        TMP$$_IND_T_NAME0


SQL> SELECT TABLE_NAME, CONSTRAINT_NAME


 2  FROM USER_CONSTRAINTS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     CONSTRAINT_NAME


------------------------------ -------------------------


T                              SYS_C0011881


T                              PK_T


T_INTER                        TMP$$_PK_T0


T_INTER                        TMP$$_SYS_C00118810


SQL> SELECT TABLE_NAME, TRIGGER_NAME


 2  FROM USER_TRIGGERS


 3  WHERE TABLE_NAME IN ('T', 'T_INTER');


TABLE_NAME                     TRIGGER_NAME


------------------------------ -------------------------


T_INTER                        TMP$$_TRI_T0


T                              TRI_T


SQL> SELECT TABLE_NAME, PARTITION_NAME


 2  FROM USER_TAB_PARTITIONS


 3  WHERE TABLE_NAME  = 'T';


TABLE_NAME                     PARTITION_NAME


------------------------------ -----------------


T                              SYS_P161


T                              SYS_P162


T                              SYS_P163


T                              SYS_P164


SQL> DROP TABLE T_INTER PURGE;


表已删除。


可以看到,利用COPY_TABLE_DEPENDENTS过程不但方面,而且执行完重定义操作后,所有的关联对象名称都不会发生变化,这确实是10g上一个很方便的改进。


oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html