oracle 9i在线重定义,Oracle在线重定义修改字段脚本_在线修改字段类型_dbms_redefinition...

– 创建测试数据

– 创建一张临时表

create table tbl_yy as

select rownum as id,

to_char(sysdate + rownum/24/3600, ‘yyyy-mm-dd hh24:mi:ss’) as inc_datetime,

trunc(dbms_random.value(0, 10000)) as random_id,

dbms_random.string(‘x’, 20) random_string

from dual

connect by level <= 10000;

commit;

– 如果觉得数据不够,可以再继续插入数据测试

insert into tbl_yy

(ID, INC_DATETIME,RANDOM_ID,RANDOM_STRING)

select rownum as id,

to_char(sysdate + rownum / 24 / 3600, ‘yyyy-mm-dd hh24:mi:ss’) as inc_datetime,

trunc(dbms_random.value(0, 100)) as random_id,

dbms_random.string(‘x’, 20) random_string

from dual

connect by level <= 100000;

commit;

– 创建临时表

– 临时表会占用主表同样的大小,要检查好表空间容量。

create table int_tbl_yy as select * from tb_yy where rownum = 0;

– 修改字段类型,number改成varchar2

alter table int_tbl_yy modify RANDOM_ID varchar2(22);

– 全局配置,变量替换,如下直接复制到sqlplus或工具执行。

– 临时表会占用主表同样的大小,要检查好表空间容量。

– 生产环境不要在业务高峰期做操作

– 用户名

define USERNAME = ‘yy’;

– 原表名

define SOURCE_TAB = ‘tbl_yy’;

– 临时表名,需要手工提前创建

define INT_TAB = ‘int_tbl_yy’;

– 映射表的字段名

– 由于define最大长度只支持240个字符,映射要在第4点自己配置col_mapping这个参数,如下是生成的方法,注意手工去掉最后一个逗号,

– 注意类型转换,如id(varchar2 要转成id(number) ,映射的时候需要保证字段类型一致,使用to_number解决,如:to_number(id) id,

– select listagg(column_name || ’ ’ || column_name || ‘,’ ) col_name from user_tab_columns where table_name=’&SOURCE_TAB’;

– 并行度

define PARALLELS = 4;

-----------分割线-执行步骤---------------------

– 1.打开并行

alter session force parallel dml parallel &PARALLELS;

alter session force parallel query parallel &PARALLELS;

– 2.重定义为分区,使用rowid,建议为临时表开启行迁移

alter table &INT_TAB enable row movement;

– 3.检查dbms_redefinition是否在这个表上工作

–基于主键

– exec DBMS_REDEFINITION.CAN_REDEF_TABLE(‘custinfo’,‘fm’,DBMS_REDEFINITION.CONS_USE_PK);

–基于rowid

begin

dbms_redefinition.can_redef_table(uname => ‘&USERNAME’,

tname => ‘&SOURCE_TAB’,

options_flag => DBMS_REDEFINITION.CONS_USE_ROWID);

end;

/

– 4.调用DBMS_REDEFINITION.START_REDEF_TABLE存储过程启动重定义进程

– 接下来开始重新定义

– BEGIN

– DBMS_REDEFINITION.START_REDEF_TABLE(UNAME =>‘custinfo’, ORIG_TABLE=>‘fm’,INT_TABLE=>‘int_fm’,OPTIONS_FLAG=>dbms_redefinition.cons_use_pk);

– END;

– 基于rowid

– number , varchar2 互转要用to_char 或to_number 做映射。

– select listagg(column_name || ’ ’ || column_name || ‘,’ ) from dba_tab_columns where table_name=upper(’&SOURCE_TAB’);

set timing on;

begin

DBMS_REDEFINITION.START_REDEF_TABLE(uname => ‘&USERNAME’,

orig_table => ‘&SOURCE_TAB’,

int_table => ‘&INT_TAB’,

col_mapping => ‘ID ID,INC_DATETIME INC_DATETIME,to_char(RANDOM_ID) RANDOM_ID,RANDOM_STRING RANDOM_STRING’,

options_flag => DBMS_REDEFINITION.CONS_USE_ROWID);

end;

/

– 5.复制依赖对象。(自动创建任何触发器、索引、物化视图日志、授予和对 custinfo.int_fm 的约束)。

– copy_indexes => 0 索引报错可以设置为0

DECLARE

num_errors PLS_INTEGER;

BEGIN

DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => ‘&USERNAME’,

orig_table => ‘&SOURCE_TAB’,

int_table => ‘&INT_TAB’,

copy_indexes => DBMS_REDEFINITION.cons_orig_params,

copy_triggers => TRUE,

copy_constraints => TRUE,

copy_privileges => TRUE,

ignore_errors => FALSE,

num_errors => num_errors,

copy_statistics => TRUE);

END;

/

– 6.利用sync_interim_table过程同步临时表的数据减少finish_redef_table的耗时:

begin

dbms_redefinition.sync_interim_table(uname => ‘&USERNAME’,

orig_table => ‘&SOURCE_TAB’,

int_table => ‘&INT_TAB’);

end;

/

-----------分割线-后面二步是结束操作,执行后会做最后阶段的切换------------

– 7.执行finish_redef_table过程完成重定义:

begin

dbms_redefinition.finish_redef_table(uname => ‘&USERNAME’,

orig_table => ‘&SOURCE_TAB’,

int_table => ‘&INT_TAB’);

end;

/

– 关掉并行

– 以上成功完成了对SALES表的Online Redefinition,由非分区表在线重定义为分区表且增加了一个字段。

– 这里因为我们使用rowid方式,所以重定义完的表上会多出一个隐藏字段, 从10.2开始M_ROW$$的隐藏列会被命名为SYS_%DATE%的形式,且默认即为unused状态:

alter session force parallel dml parallel 1;

alter session force parallel query parallel 1;

alter table &SOURCE_TAB drop unused columns;

select * from dba_unused_col_tabs ;

– 删除临时表

alter table &INT_TAB nologging;

drop table &INT_TAB;

-------------------------分割线-结束--------------------------------

– 异常处理

– 如果失败了可以取消

– begin

– dbms_redefinition.abort_redef_table(

– uname => ‘&USERNAME’,

– orig_table => ‘&SOURCE_TAB’,

– int_table => ‘&INT_TAB’);

– end;

– /

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值