金蝶云星空在ORACLE19C数据库环境遇上的ORA-01450错误的处理方法
--1、遇上问题:前几天,在指导客户使用导入的方法,创建数据中心时,遇上下面的错误
字面意思很明显,索引键值的长度,超过了最大值6398个字节,
--2、分析原因:第一次在这环境遇上这错误,很纳闷,什么字段值的数据类型这么长?到测试环境查看,4000字节,
--2.2、反馈客户,客户查看,他的环境,这字段的长度却是32767字节,
瞬间明白,客户的数据库环境,启用了12C的新特性,字符类的长度,可以达32K,这是相对11G版本的说法,在11G,表字段的字符数据类型,最大只能是4000字节;到了12C,新增了32K长度的新特性,也就是设置了max_string_size=32K属性后,字符类型字段的长度,最大可达32K。
--3、重现问题:搭建19C的测试环境,并启用32K的新特性,就是数据库参数,max_string_size=32K,然后模拟:
3.1、在11204环境,使用脚本创建 T_BD_FLEXITEMDETAILV 表(新建两表,一个原始结构,另外一个,表字段长度3999,主要是想测试,此长度下,是否触发扩展到32767值),
然后导出两表,把DMP文件,导入到19C的环境,结果正常: T_BD_FLEXITEMDETAILV_4000.FCALCOL
的数据类型长度,也是4000,并未变成为 32767。
3.2、往这两表里导入10条数据,然后重复3.1步骤,结果还是正常,,,没能模拟出故障,意味着没环境供分析,客户的问题无从下手,陷入困境,
3.3、和领域的同事反馈,他说,这个索引是业务需求,必须保证该字段唯一性。
3.4、回想下客户的情形,觉得还可以按用户来作导出、导入测试,因为原始情况就是这样。于是在11G环境,新建了账号,然后重复3.1步骤,再在19C环境,新建个账号来接收数据,这次,故障果然出现了,
而3999长度的表,则正常导入,没自动扩展到32767长度,
换句话说,要触发这BUG,必须满足这几个条件:
1、数据库环境,必须启用12c版本的新特性max_string_size=extended。
2、dmp文件中,表字段的长度,必须是4000字符。
3、按用户导入库。
--4、修复思路:和领域同事讨论了问题的前因后果,说明BUG的触发条件;经计算,把这字段的数据类型长度,缩短到3600字节。
--5、BUG在下个大版本中完善,对于当前版本,重定义该表即可,具体步骤如下:
5.1 使用SQLPLUS工具,以数据中心账号的身份,登录数据库,执行以下脚本:
BEGIN
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'TABLESPACE',FALSE);
END;
/
set long 9999;
set pagesize 203;
select dbms_metadata.get_ddl('TABLE','T_BD_FLEXITEMDETAILV','') from dual;
--5.2 上述命令,将获取该表的表结构,大致如下:
--5.2.1
CREATE TABLE "KDSA"."T_BD_FLEXITEMDETAILV"
( "FID" NUMBER(10,0) NOT NULL ENABLE,
"FOPCODE" NVARCHAR2(10) COLLATE "USING_NLS_COMP" DEFAULT ' ',
"FFLEX4" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX5" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX6" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX7" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX8" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX9" NUMBER(10,0) DEFAULT 0,
"FFLEX10" NUMBER(10,0) DEFAULT 0,
"FFLEX11" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX12" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX13" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX14" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX15" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FFLEX16" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE,
"FCALCOL" VARCHAR2(32767) COLLATE "USING_NLS_COMP" GENERATED ALWAYS AS
(TRIM(TO_CHAR("FFLEX4"))||'_'||TRIM(TO_CHAR("FFLEX5"))||'_'||TRIM(TO_CHAR("FFLEX6"))||'_'||
TRIM(TO_CHAR("FFLEX7"))||'_'||TRIM(TO_CHAR("FFLEX8"))||'_'||TRIM(TO_CHAR("FFLEX9"))||'_'||
TRIM(TO_CHAR("FFLEX10"))||'_'||TRIM(TO_CHAR("FFLEX11"))||'_'||TRIM(TO_CHAR("FFLEX12"))||'_'||
TRIM(TO_CHAR("FFLEX13"))||'_'||TRIM(TO_CHAR("FFLEX14"))||'_'||TRIM(TO_CHAR("FFLEX15"))||'_'||
TRIM(TO_CHAR("FFLEX16"))) VIRTUAL) DEFAULT COLLATION "USING_NLS_COMP"
--5.2.2
CREATE UNIQUE INDEX "PK_BD_FLEXITEMDETAILV" ON "T_BD_FLEXITEMDETAILV" ("FID")
--5.2.3
ALTER TABLE "T_BD_FLEXITEMDETAILV" ADD CONSTRAINT "PK_BD_FLEXITEMDETAILV" PRIMARY KEY ("FID") USING INDEX PK_BD_FLEXITEMDETAILV ENABLE
--5.2.4(这个脚本是手工编写)
CREATE UNIQUE INDEX "IDX_FLEXITEMUNIQUE" ON "T_BD_FLEXITEMDETAILV" ("FCALCOL");
把 32767 ,改成 3600,然后定义新表名,新的主键索引名,新建FCALCOL字段的唯一性索引(5.2.4步骤),再把原表的数据,插入到新表中,然后删除原表,再把新表名,改成原表名。
需要提醒的时,此方法,只能在表的数据处于静止状态才能执行,若不能保证这一点,那需要用表在线重定义的方法,确保重定义
金蝶云星空在ORACLE19C数据库环境遇上的ORA-01450错误的处理方法
本文2024-09-23 01:15:33发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-144798.html