⼀次较为完整的oracle数据库数据迁移过程
作为⼀个后端开发者, 需要处理的问题会⾮常多⾮常杂,不断的接触各⽅⾯的知识,总结⼼得才能有所提⾼。
最近我们将甲⽅的信披系统改造后并⼊了我们的系统,开发基本完成,接下来数据迁移就是⼀个⼤问题了。因为之前其它开发商系统的数据库设计极烂,所以这次数据迁移稍微显得⿇烦,⽽数据迁移最⼤的要求就是保证数据的正确性。
在此把这次迁移的⽅式记录下来,也希望以后有所提升之后能有更好的⽅案。
总体的⽅案上 是先把原库的表导⼊到我们库,然后写存储过程,对重构的字段做对应,然后导⼊到我们的新表之中,最后删除⽼的表。
原库的表导⼊我们库 我们在这⾥⽤到的是oracle的 exp imp命令
注意exp imp命令直接在dos下运⾏就⾏ 不需要进⼊sqlplus
下⾯是exp命令和imp命令
Exp disinfo2/disinfo2@disinfo2 log=disinfo_emp.log file=C:\Users\hundsun\Desktop\cbs信披改造迁移数据\dmp\disinfo.dmp
tables =(TBL_INFO_DISCLOSUER_APPLY,TBL_DISCLOSUER_APPLY_FILE,TBL_FILE_PATH,TBL_FILE_INFO,TBL_INFO_DISCLOSUER_HANDLE_LO imp cfae_cbs/hundsun@1538CBS log=disinfo_imp.log file=C:\Users\hundsun\Desktop\cbs信披改造迁移数据\dmp\disinfo.dmp
tables =(TBL_INFO_DISCLOSUER_APPLY,TBL_DISCLOSUER_APPLY_FILE,TBL_FILE_PATH,TBL_FILE_INFO,TBL_INFO_DISCLOSUER_HANDLE_LO 意思应该都明确易懂, ⽤户名/密码 连接 ⽇志输出地址 需要导⼊或导出的表。 ⽂件做成bat或sh直接运⾏就可以了 ⾮常的⽅便快捷。
这样所有我需要的表都转移到我们⾃⼰的库⾥⾯。
下⼀步就是写存储过程,重构对应字段了。
下⾯是主表的迁移存储过程 关键的地⽅我添加了注释解释⼀下
create or replace procedure sp_disinfo_apply_insert
as
--原信披库申请表中存储了所有历史数据先改造成之前版本进⼊历史表所以进⼊申请表的数据只为版本号最⾼的数据
cursor cur_infordis_apply is --此处是游标批量导⼊数据基本都需要⽤到相当于把数据做成⼀个list ⽅便之后foreach的循环导⼊
select t.* from
( select apply_id,
title,
status,
is_directional,
biz_resource,
publish_method,
is_cron_disclosure,
announcement_type_name,
announcement_type_id,
DISCLOSUER_INSTITUTION,
disclosuer_institution_name,
rp_disclosuer_institution,
rp_disclosuer_institution_name,
publisher_mem_code,
bond_id,
bond_code,
bond_short_name,
bond_full_name,
bond_type,
contact_phone,
contact_user,
area_code,
tel_number,
contact_email,
is_check,
remarks,
create_user_id,
update_user_id,
update_user_name,
oper_user_id,
registrstion_notice_paper_no,
create_time,
update_time,
cron_publish_time,
disclosure_time,
tranfer_times,
--此处这个row_number()over partition by 的⽤法⽤于到之前版本最⾼的数据因为原库中没有设计历史表所有历史数据全在主表⾥⾯靠⼀个版本字段做区分
--这样做⾮常不好数据很乱所以我们做了改动这⾥我们需要拿到最⾼版本的数据
row_number() over(partition by apply_id order by tranfer_times desc) rn from tbl_info_disclosuer_apply)t
where rn=1;
begin
for apply in cur_infordis_apply
loop
--if apply.title='重复测试-001' then
DBMS_OUTPUT.ENABLE(buffer_size => null);
-- 发布类型映射,例:PDF⽅式->1
--申明变量
declare
--publish_method
--publish_method
v_old_method varchar2(200);
v_new_method number;
--申请类型
v_old_type varchar2(200);
v_new_type varchar2(2);
--所有时间字段
v_old_create_date date;
v_old_update_date date;
v_old_cron_date date;
v_old_disclosure_date date;
v_new_create_date number(10);
v_new_create_time number(10);
v_new_update_date number(10);
v_new_update_time number(10);
v_new_cron_date number(10);
v_new_cron_time number(10);
v_new_disclosure_date number(10);
v_new_disclosure_time number(10);oracle 时间转换
--区号
v_old_area varchar2(160);
v_new_area varchar2(6);
-
-版本号
v_old_trans number(10);
v_new_trans varchar(32);
begin
--publish_method转换
v_old_method := apply.publish_method;
if v_old_method='PDF⽅式' then
v_new_method := 1;
ELSE v_new_method := 2;
end if;
--所有时间字段
v_old_create_date := ate_time;
v_old_update_date := apply.update_time;
v_old_cron_date := _publish_time;
v_old_disclosure_date := apply.disclosure_time;
v_new_create_date:= TO_NUMBER(TO_CHAR(v_old_create_date, 'YYYYMMDD')) ;
v_new_create_time:= TO_NUMBER(TO_CHAR(v_old_create_date, 'hh24miss')) ;
v_new_update_date:= TO_NUMBER(TO_CHAR(v_old_update_date, 'YYYYMMDD')) ;
v_new_update_time:= TO_NUMBER(TO_CHAR(v_old_update_date, 'hh24miss')) ;
v_new_cron_date:= TO_NUMBER(TO_CHAR(v_old_cron_date, 'YYYYMMDD')) ;
v_new_cron_time:= TO_NUMBER(TO_CHAR(v_old_cron_date, 'hh24miss')) ;
v_new_disclosure_date:= TO_NUMBER(TO_CHAR(v_old_disclosure_date, 'YYYYMMDD')) ; v_new_disclosure_time:= TO_NUMBER(TO_CHAR(v_old_disclosure_date, 'hh24miss')) ;
--申请类型转换
v_old_type := apply.announcement_type_name;
CASE v_old_type
WHEN '挂牌⽂件' THEN v_new_type:='1';
WHEN '其他与挂牌相关的事项' THEN v_new_type:='2';
WHEN '挂牌结果公告' THEN v_new_type:='3';
WHEN '财务报告及摘要' THEN v_new_type:='4';
WHEN '信⽤评级公告' THEN v_new_type:='5';
WHEN '重⼤事项公告' THEN v_new_type:='6';
WHEN '持有⼈会议公告' THEN v_new_type:='7';
WHEN '本息资⾦划转公告' THEN v_new_type:='8';
WHEN '未按期⾜额偿付本息公告' THEN v_new_type:='9';
WHEN '其它' THEN v_new_type:='10';
else v_new_type:=null;
END case ;
--区号截取
v_old_area:=apply.area_code;
if lengthb(v_old_area)>6 then
v_new_area:=SUBSTRB(v_old_area,0,6);
elsif v_old_area is null then
v_new_area:='';
else
v_new_area:=v_old_area;
end if;
dbms_output.put_line(apply.title);
dbms_output.put_line(apply.apply_id);
dbms_output.put_anfer_times);
--插⼊数据
insert into infodis_apply
(apply_id,
title,
disclosure_status,
is_directional,
biz_resource,
is_cron_disclosure,
disclosure_method,
disclosure_type,
disclosure_agency,
disclosure_agency_name,
disclosure_client,
disclosure_client_name,
publisher_mem_code,
bond_id,
bond_code,
bond_short_name,
bond_full_name,
bond_type,
contact_phone,
contact_name,
area_code,
tel_number,
contact_email,
is_check,
remark,
create_user_id,
update_user_id,
update_user_name,
oper_user_id,
reg_notice_number,
create_date,
create_time,
update_date,
update_time,
cron_publish_date,
cron_publish_time,
disclosure_date,
disclosure_time)
values( apply.apply_id,
apply.title,
apply.status,
apply.is_directional,
apply.biz_resource,
apply.is_cron_disclosure,
v_new_method,
v_new_type,
apply.DISCLOSUER_INSTITUTION,
apply.disclosuer_institution_name,
apply.rp_disclosuer_institution,
apply.rp_disclosuer_institution_name,
apply.publisher_mem_code,
apply.bond_id,
apply.bond_code,
apply.bond_short_name,
apply.bond_short_name,
apply.bond_full_name,
apply.bond_type,
v_new_area,
apply.is_check,
apply.update_user_id,
apply.update_user_name,
apply.oper_user_id,
v_new_create_date,
v_new_create_time,
v_new_update_date,
v_new_update_time,
v_new_cron_date,
v_new_cron_time,
v_new_disclosure_date,
v_new_disclosure_time);
commit;
end;
-- end if;
END loop;
end sp_disinfo_apply_insert;
之后的所有表也都按照此存储过程的模式写好存储过程导⼊。
这⾥还有需要优化的地⽅ 不同的字段对应⽅法可以写成function 可能会出现复⽤的情况。 可以写⼀个主过程来调⽤所有的存储过程⼀次性导⼊。
总之可能⾃⼰接触的东西有限还有很多复杂得多的数据迁移需要实现,希望在之后不断学习,总结更好的⽅法。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论