`
mizhao1984
  • 浏览: 88359 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论
阅读更多
查看是否支持分区(Partitioning是否为true)
select * from v$option s order by s.PARAMETER desc


Oracle 在线重定义表
步骤:
1)Check 原表A 是否可以重定义
   EXECUTE dbms_redefinition.can_redef_table (user, 'table_name');
2)创建一个中间表B,其结构是你想要对表A进行重定义的最终结构。这里的结构指表列结构、主键(必须),不包含索引,约束,触发器,用户权限等;
3)关联中间表 B 与原表 A
   EXECUTE dbms_redefinition.start_redef_table ('user', 'A', 'B', COL_MAPPING, OPTIONS_FLAG);
   此时,oracle 会创建一个物化视图,将原表A的所有数据拷贝到中间表B中。此过程不会影响用户对A表的访问。
主要参数:
UNAME        VARCHAR2 IN
ORIG_TABLE   VARCHAR2 IN
INT_TABLE    VARCHAR2 IN
COL_MAPPING  VARCHAR2 IN DEFAULT
OPTIONS_FLAG BINARY_INTEGER IN DEFAULT
ORDERBY_COLS VARCHAR2 IN DEFAULT
PART_NAME    VARCHAR2 IN DEFAULT
其中:
COL_MAPPING:列的映射关系。默认所有包括在中间表中的列用于表的重定义。如果给出了映射方法,则只考虑映射方法中给出的列;
OPTIONS_FLAG:重定义的方法,默认基于主键。dbms_redefinition.cons_use_pk和dbms_redefinition.cons_use_rowid。
4)在中间表B上创建所需的索引,约束,触发器,用户权限等
5)用中间表redefine原表
   Exec dbms_redefinition.finish_redef_table(‘user’, 'A', 'B’);
   oracle会根据step 3)的物化视图,把原表A的最新数据增量更新到中间表B;然后在数据字典中把原表和中间表对换,对换的过程原表A将处于锁状态(排它锁)。结束后,中间表B重命名成了原表A。此时可以删除中间表B。
   如果在执行dbms_redefinition.start_redef_table()过程和执行dbms_redefinition.finish_redef_table()过程直接在重定义表上执行了大量的DML操作,那么可以选择执行一次或多次的sync_interim_table()过程,以减少最后一步执行finish_redef_table()过程时的锁定时间。



在线重定义使用的例子:
SQL> create table test_primary (id number primary key);
表已创建。
SQL> insert into test_primary select rownum from dba_objects;
已创建6264行。
SQL> commit;
提交完成。
SQL> create table orgin_table (id number, fid number, name varchar2(30), create_date date)
  2  tablespace users;
表已创建。
SQL> insert into orgin_table select rownum, rownum, object_name, created from dba_objects
  2  where owner = 'SYS';
已创建4034行。
SQL> commit;
提交完成。
SQL> alter table orgin_table add constraint pk_orgin_table primary key (id);
表已更改。
SQL> create or replace trigger tr_orgin_table
  2  before insert on orgin_table for each row
  3  begin
  4  null;
  5  end;
  6  /
触发器已创建
SQL> create index ind_orgin_table_create_date on orgin_table(create_date);
索引已创建。
SQL> alter table orgin_table add constraint f_orgin_primary_id foreign key (fid)
  2  references test_primary (id);
表已更改。
SQL> begin
  2  dbms_redefinition.can_redef_table('yangtk', 'orgin_table', dbms_redefinition.cons_use_pk);
  3  end;
  4  /
PL/SQL 过程已成功完成。
SQL> create table inter_table
  2  (id number, fid number, new_name varchar2(30), create_date date, comments varchar2(1000))
  3  tablespace yangtk
  4  partition by range (create_date)
  5  (partition p1 values less than (to_date('2005-1-1', 'yyyy-mm-dd')),
  6  partition p2 values less than (maxvalue));
表已创建。
SQL> alter table inter_table add constraint pk_inter_table primary key (id);
表已更改。
SQL> begin
  2  dbms_redefinition.start_redef_table('yangtk', 'orgin_table', 'inter_table',
  3  'ID ID, FID FID, NAME NEW_NAME, CREATE_DATE CREATE_DATE, ''NO COMMENTS'' COMMENTS',
  4  DBMS_REDEFINITION.CONS_USE_PK);
  5  END;
  6  /
PL/SQL 过程已成功完成。
SQL> SELECT COUNT(*) FROM INTER_TABLE;
  COUNT(*)
----------
      4034
SQL> COL COMMENTS FORMAT A20
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
会话已更改。
SQL> SELECT * FROM INTER_TABLE WHERE ID = 1;
        ID        FID NEW_NAME     CREATE_DATE         COMMENTS
---------- ---------- ------------ ------------------- --------------------
         1          1 ACCESS$      2004-10-18 16:14:23 NO COMMENTS
SQL> INSERT INTO ORGIN_TABLE
  2  SELECT 4034+ROWNUM, 4034+ROWNUM, OBJECT_NAME, CREATED FROM DBA_OBJECTS
  3  WHERE OWNER = 'SYSTEM';
已创建404行。
SQL> COMMIT;
提交完成。
SQL> begin
  2  dbms_redefinition.sync_interim_table('yangtk', 'orgin_table', 'inter_table');
  3  end;
  4  /
PL/SQL 过程已成功完成。
SQL> select count(*) from INTER_TABLE;
  COUNT(*)
----------
      4438
SQL> alter table inter_table add constraint fk_inter_primary_id foreign key (fid)
  2  references test_primary (id) disable;
表已更改。
SQL> create index ind_inter_table_date on inter_table(create_date);
索引已创建。
SQL> create index ind_inter_table_fid on inter_table(fid);
索引已创建。
SQL> create or replace trigger tr_inter_table
  2  before insert on inter_table for each row
  3  begin
  4  null;
  5  end;
  6  /
触发器已创建
SQL> begin
  2  dbms_redefinition.finish_redef_table('yangtk', 'orgin_table', 'inter_table');
  3  end;
  4  /
PL/SQL 过程已成功完成。
SQL> desc orgin_table
名称                            是否为空? 类型
------------------------------- -------- ---------------
ID                              NOT NULL NUMBER
FID                                      NUMBER
NEW_NAME                                 VARCHAR2(30)
CREATE_DATE                              DATE
COMMENTS                                 VARCHAR2(1000)
SQL> select table_name, partition_name from user_tab_partitions where table_name = 'ORGIN_TABLE';
TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------
ORGIN_TABLE                    P1
ORGIN_TABLE                    P2
SQL> select table_name, constraint_name, status from user_constraints
  2  where table_name in ('ORGIN_TABLE', 'INTER_TABLE');
TABLE_NAME           CONSTRAINT_NAME            STATUS
-------------------- -------------------------- --------
INTER_TABLE          PK_ORGIN_TABLE             ENABLED
INTER_TABLE          F_ORGIN_PRIMARY_ID         DISABLED
ORGIN_TABLE          PK_INTER_TABLE             ENABLED
ORGIN_TABLE          FK_INTER_PRIMARY_ID        ENABLED
SQL> SELECT COUNT(*) FROM ORGIN_TABLE;
  COUNT(*)
----------
      4438
SQL> SELECT COUNT(*) FROM INTER_TABLE;
  COUNT(*)
----------
      4438
SQL> DROP TABLE INTER_TABLE;
表已丢弃。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics