达梦以字符为单位数据导入到以字节为单位(逻辑导出导入)处理过程

最近在工作中用户需要将一些老版本的数据库迁移到新版本的数据库中,因安全问题服务器之间的网络是无法开通的。无法使用dts进行迁移。只能使用dexp/dimp逻辑迁移的方式进行数据迁移。达梦老版本是以字符为单位,而新版本已经取消了以字符为单位的,在导入过程中出现很多字符串截断的错误。

 由于新版本无LENGTH_IN_CHAR参数,可以先导入表结构,将模式下面所有表里面varchar字段扩大3倍之后,再进行数据导入

declare CURSOR cur is
select * from DBA_TAB_COLUMNS where owner='模式名' and data_type ='VARCHAR' ;
begin
for i in cur LOOP
execute immediate 'alter table '||i.owner||'.'||i.table_name||' modify '||i.column_name||' varchar('||3 * i.data_length||');';
end loop;
end;
在批量修改字段时,提示有不能修改或删除聚集索引的列错误

 尝试将PK_WITH_CLUSTER改成0,重新导入去掉约束也不行,ddl建表语句还是源库一样的。尝试先禁用主外键,在过程中非聚集主键的可以禁用,聚集主键的报错

 一般主键没有中文字符,可以将主键字段过滤,主键字段是varchar类型的长度不扩大

 declare CURSOR cur is
select * from DBA_TAB_COLUMNS where owner='模式名' and data_type ='VARCHAR' and column_name not in (
SELECT DISTINCT(ALL_CONS_COLUMNS.column_name)
FROM SYSCONS, SYSOBJECTS, ALL_CONS_COLUMNS
WHERE SYSCONS.id=SYSOBJECTS.id
AND SYSCONS.TYPE$='P'
AND SYSOBJECTS.name=ALL_CONS_COLUMNS.CONSTRAINT_NAME
AND ALL_CONS_COLUMNS.OWNER='模式名'
) ;
begin
for i in cur LOOP
execute immediate 'alter table '||i.owner||'.'||i.table_name||' modify '||i.column_name||' varchar('||3 * i.data_length||');';
end loop;
end;
执行过程有数据精度超出范围的错误

 这里有varchar类型长度超过10000的过滤掉,用户下所有varchar字段大于10000的的都换成clob

declare CURSOR cur is
select * from DBA_TAB_COLUMNS where owner='模式名' and data_type ='VARCHAR' and data_length>10000;
begin
for i in cur LOOP
execute immediate 'alter table '||i.owner||'.'||i.table_name||' add column ('||i.column_name||'_2 clob)';
execute immediate 'alter table '||i.owner||'.'||i.table_name||' drop column '||i.column_name;
execute immediate 'alter table '||i.owner||'.'||i.table_name||' rename column '||i.column_name||'_2 to '||i.column_name;
end loop;
end;
不能同时包含聚集key和大字段的错误

 对报错的表进行处理,将聚集主键的表删除重建一个非聚集主键的表,再将超长的varchar字段改成clob类型,该方法还是有很多表报错需要一个个处理,浪费时间多

现采用另外一种方案是除主键外,将其他varchar类型的字段改成varchar(n char);
 declare CURSOR cur is
select * from DBA_TAB_COLUMNS where owner='模式名' and  data_type ='VARCHAR' and  column_name not in (
SELECT DISTINCT(ALL_CONS_COLUMNS.column_name)
FROM SYSCONS, SYSOBJECTS, ALL_CONS_COLUMNS
WHERE SYSCONS.id=SYSOBJECTS.id
AND SYSCONS.TYPE$='P'
AND SYSOBJECTS.name=ALL_CONS_COLUMNS.CONSTRAINT_NAME
AND ALL_CONS_COLUMNS.OWNER='模式名'
) ;
begin
for i in cur LOOP
execute immediate 'alter table  '||i.owner||'.'||i.table_name||' modify '||i.column_name||'  varchar('||i.data_length||' char);';
end loop;
end;
有如下报错

 执行如下sql,将结果集全部展示在新窗口执行

 select 'alter table  '||i.owner||'.'||i.table_name||' modify '||i.column_name||'  varchar('||i.data_length||' char);' from DBA_TAB_COLUMNS i where i.owner='模式名' and  i.data_type ='VARCHAR' and  i.column_name not in (
SELECT DISTINCT(ALL_CONS_COLUMNS.column_name)
FROM SYSCONS, SYSOBJECTS, ALL_CONS_COLUMNS
WHERE SYSCONS.id=SYSOBJECTS.id
AND SYSCONS.TYPE$='P'
AND SYSOBJECTS.name=ALL_CONS_COLUMNS.CONSTRAINT_NAME
AND ALL_CONS_COLUMNS.OWNER='模式名'
在客户端工具窗口-选项-查询分析器里面设置错后弹窗提示如果执行有报错会有提示,记录下来,继续执行,这里很少有这种不是主键的聚集索引

 这个表有一个聚集索引

 将这个索引删除,新建一个普通索引,然后再进行修改。这种方案工作量小,基本很少有报错的需要处理,但导入还是报超出字段定义的问题,

应该是老版本以前对表开了超长记录, 新版本对这个表开启超长记录没用,还是报错,可以将这个表varcahr类型扩大3倍处理

posted @   fangzpa  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
点击右上角即可分享
微信分享提示