达梦length_in_char参数影响数据迁移问题处理
达梦数据库新老版本间因length_in_char参数不同,而导致的dexp/dimp逻辑迁移问题处理
因达梦数据库 新版本取消了 length_in_char 参数,老版本做dexp/dimp数据迁移时,会出现"string trunc" 的报错,影响数据完整性;
因为 length_in_char 参数主要是影响 varchar 、 varchar2 类型,故可以在数据库中查询到varchar 类型,并扩大对应的字段精度。
----查询所有的varchar 类型
select * from DBA_TAB_COLUMNS where owner='ANONYMOUS' and data_type ='VARCHAR' ;
–把ANONYMOUS用户下所有字段是varchar类型长度全部扩大3倍
declare
CURSOR cur is
select
*
from
DBA_TAB_COLUMNS
where
owner = 'ANONYMOUS'
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;
可能出现的报错:
1、-2865:不能修改或删除聚集索引的列
2、-6121:数据精度超出范围
3、-3242:表中不能同时包含聚集 KEY 和大字段
4、-2528:物化视图和日志表不支持当前操作
聚集主键可以通过两个方式处理 :
① 将达梦的 PK_WITH_CLUSTER 参数改为 0 ,重新导入表结构创建表;但是当源库的DDL用的是聚集主键时,仍无法处理该报错;
② 将导出的dmp文件导入表结构到本地达梦库,通过dts的导入已修改为非聚集主键,且字段精度已扩大4倍的表结构SQL脚本;执行新的DDL sql脚本后,再通过dmp文件导入数据
DATA_ONLY = Y --只导入表数据
③ 过滤主键字段,不做修改;使用如下语句进行修改除主键外的所有varchar字段;可将下述两种方式结合起来,既扩大字段精度,也修改存储方式 ;2 * varchar n char
该方式可能出现,“数据精度超出范围”的报错,下述语句中提供部分解决方案
----将除主键外的所有varchar字段精度扩大3倍(不推荐)
declare
CURSOR cur is
select
*
from
DBA_TAB_COLUMNS
where
owner = 'ANONYMOUS'
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 = 'ANONYMOUS');
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字段修改为varchar(n char) 的表达方式 (推荐该方式)
declare
CURSOR cur is
select
*
from
DBA_TAB_COLUMNS
where
owner = 'ANONYMOUS'
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 = 'ANONYMOUS');
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;
----- -6121: 数据精度超出范围
-----varchar字段粗暴的扩大3倍的方式,varchar字段精度可能会超出范围,此时可以通过以下语句,将varchar精度超过10000的字段修改为大字段clob;
-----该方式仅能解决非聚集主键的表数据导入
-----聚集主键会报错 “不能同时包含聚集KEY和大字段”
declare
CURSOR cur is
select
*
from
DBA_TAB_COLUMNS
where
owner = 'ANONYMOUS'
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;
--------[-2528]:物化视图和日志表不支持当前操作
--------可通过以下方式绕过: (除去物化视图与物化视图日志表)
declare
CURSOR cur is
select * from DBA_TAB_COLUMNS where owner='ANONYMOUS' and data_type ='VARCHAR'
and table_name in (select table_name from dba_tables where owner='ANONYMOUS' and table_name not like 'MTAB$%') ;
begin
for i in cur LOOP
execute immediate 'alter table ' || i.owner || '.' || i.table_name || ' modify ' || i.column_name || ' varchar(' || 3 * i.data_length || ');';
print ( i.owner || '.' || i.table_name ||' 表中的 ' ||i.column_name ||' 字段已修改');
end loop;
end;
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)