oracle2kingbase的字段长度问题
实验一:
oracle中:
create table testlen(c1 varchar2(2));
insert into testlen values('山'); --成功
insert into testlen values('山西'); --失败
ORA-12899: 列 "TESTK"."TESTLEN"."C1" 的值太大 (实际值: 4, 最大值: 2)
结果:oracle中默认是按字节计算长度的。
-----------------------------------
kingbase中:
test=# select version();
version
--------------------------------------------------------------------------------
KingbaseES V008R006C009B0014 on x64, compiled by Visual C++ build 1800, 64-bit
(1 行记录)
test=# SHOW nls_length_semantics;
nls_length_semantics
----------------------
char
(1 行记录)
create table testlenc(c1 varchar2(2));
insert into testlenc values('山西'); --成功
insert into testlenc values('山西省');
ERROR: value too large for column "public"."testlenc"."c1" (actual:3, maximum:2)
实验二:
alter system set nls_length_semantics='BYTE';
SELECT pg_reload_conf();
create table testlenb(c1 varchar2(2));
insert into testlenb values('山西');
ERROR: value too large for column "public"."testlenb"."c1" (actual:4, maximum:2)
insert into testlenb values('山'); --成功
insert into testlenc values('山西'); --仍为成功
insert into testlenc values('山西省'); --仍为失败
SELECT column_name,data_type,character_maximum_length FROM information_schema.columns WHERE table_name = 'testlen';
column_name | data_type | character_maximum_length
-------------+-----------+--------------------------
c1 | varchar | 2
(1 行记录)
SELECT column_name,data_type,character_maximum_length FROM information_schema.columns WHERE table_name = 'testlenb';
column_name | data_type | character_maximum_length
-------------+-------------+--------------------------
c1 | varcharbyte |
(1 行记录)
实验三:
nls_length_semantics修改为byte后,采用KDTS从oracle迁移到KingbaseV8R6中:
testlen的varchar2(2)仍然是2个字符即2个汉字,并不是2个字节。
insert into testlen values('山西'); --成功
insert into testlen values('山西省'); --失败
SQL 错误 [22001]: ERROR: value too large for column "testk"."testlen"."c1" (actual:3, maximum:2)
结论:
1、kingbase中nls_length_semantics默认为char,varchar2(2)可以存放2个汉字。
2、当把nls_length_semantics改为byte后,varchar2(2)只能存放2个字节。
3、nls_length_semantics的值对创建表时起作用,与insert时无关。
所以要在迁移数据库前就确定好nls_length_semantics的值。
存在问题:
1、KDTS从oracle迁移到kingbase时,无论nls_length_semantics是什么值,oracle中的VARCHAR2(2)都会迁移为character varying(2 char),2字节成了2个字符长度。
也就是oracle中只有2字节的字段,迁移到kingbase后变成了4个字节长度。
SELECT column_name,data_type,character_maximum_length FROM information_schema.columns WHERE table_name = 'testlen';