我使用在线重定义表的原因是:修改表的某字段为LOB型、将大表修改为分区表、修改表的存储结构使其生效(pctfree、freelists)。
对有主键的表做在线重定义:
1.检查表是否可在线重定义
SQL> exec dbms_redefinition.can_redef_table('USER','T');
无异常说明可在线重定义
2.建立中间表,如果是生产库,建议同时建立相关索引,虽然速度可能受到影响,但总比切换时影响到使用该索引的SQL好吧!
SQL> create table t_m as select * from t;
3.复制数据
SQL> exec dbms_redefinition.start_redef_table('USER','T','T_M');
4.同步并切换
SQL> exec dbms_redefinition.finish_redef_table('USER','T','T_M');
此至,两个表做了切换,在线重定义完成。
无主键的表做在线重定义(使用rowid在线重定义):
1.检查表是否可在线重定义
SQL> exec dbms_redefinition.can_redef_table('USER','T',dbms_redefinition.cons_use_rowid);
无异常说明可在线重定义
2.建立中间表,如果是生产库,建议同时建立相关索引,虽然速度可能受到影响,但总比切换时影响到使用该索引的SQL好吧!
SQL> create table t_m as select * from t;
3.复制数据
SQL> execute dbms_redefinition.start_redef_table('USER','T','T_M','id id','name name',dbms_redefinition.cons_use_rowid);
注意,这里要把两个表的所有字段一一对应起来,如例中的:'id id','name name'。
4.同步并切换
SQL> exec dbms_redefinition.finish_redef_table('USER','T','T_M');
此至,两个表做了切换,在线重定义完成。
使用ROWID方式重定义的表,在表中会生成一个隐含列M_ROW$$
SQL> select col#,name,type# from SYS.COL$ WHERE OBJ#=(select object_id from dba_objects where object_name='T');
可以通过以下语句删除:
SQL> alter table t set unused (m_row$$);
表已更改。
SQL> alter table t drop unused columns;
表已更改。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17997/viewspace-281012/ ,如需转载,请注明出处,否则将追究法律责任。