达梦以字符为单位数据导入到以字节为单位(逻辑导出导入)处理过程
最近在工作中用户需要将一些老版本的数据库迁移到新版本的数据库中,因安全问题服务器之间的网络是无法开通的。无法使用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倍处理
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业