版本说明
CentOS 7.2
GS 3.2
问题描述
在执行SQL脚本过程中提示存在无效的字符值,报错信息如下。
COMMENT ON TABLE "T1" IS '测试表';
ERR-22021(12121): invalid character value in characterset repertoire
此时使用vi编辑该sql脚本,会出现乱码,使用cat可以正常显示内容。
DROP TABLE T1;
CREATE TABLE T1 (
ID NUMBER(10),
NAME VARCHAR2(20)
);
INSERT INTO "T1" VALUES (1,'օС¾´');
INSERT INTO "T1" VALUES (2,'n±֧);
INSERT INTO "T1" VALUES (3,'̴ǥ');
COMMENT ON TABLE "T1" IS '²㋔±륻
COMMENT ON COLUMN "T1"."ID" IS 'ʭ·܉D';
COMMENT ON COLUMN "T1"."ID" IS 'ѕĻ';
分析
从提示信息上看,属于字符相关设置不正确,首先看执行的SQL脚本内容如下。
$ cat test.sql
DROP TABLE T1;
CREATE TABLE T1 (
ID NUMBER(10),
NAME VARCHAR2(20)
);
INSERT INTO "T1" VALUES (1,'张小敬');
INSERT INTO "T1" VALUES (2,'李必');
INSERT INTO "T1" VALUES (3,'檀棋');
COMMENT ON TABLE "T1" IS '测试表';
COMMENT ON COLUMN "T1"."ID" IS '身份ID';
COMMENT ON COLUMN "T1"."ID" IS '姓名';
当前使用的终端为Xshell,编码语言为Unicode(UTF-8),接着检查数据库字符集、操作系统字符集设置。
> select PROPERTY_NAME,PROPERTY_VALUE,INIT_VALUE from v$property where PROPERTY_NAME='CHARACTER_SET';
PROPERTY_NAME PROPERTY_VALUE INIT_VALUE
------------- -------------- ----------
CHARACTER_SET UTF8 UTF8
1 row selected.
数据库当前字符集设置为UTF8,接着查看操作系统相关配置。
$ env|grep LANG
LANG=en_US.UTF-8
$ locale
LANG=en_US.UTF-8
LC_CTYPE=zh_CN.GB18030
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
注意在以上输出信息中LC_CTYPE的值设置为“zh_CN.GB18030”,查看了下其他测试机,该参数值为en_US.UTF-8。
解决方案
修改LC_CTYPE为en_US.UTF-8,乱码问题立即消除,暂没找到详细资料参数LC_CTYPE具体的含义和用法,后续补充。
$ export LC_CTYPE=en_US.UTF-8
gSQl> \import 'test.sql'
DROP TABLE T1;
Table dropped.
CREATE TABLE T1 (
ID NUMBER(10),
NAME VARCHAR2(20)
);
Table created.
INSERT INTO "T1" VALUES (1,'张小敬');
1 row created.
INSERT INTO "T1" VALUES (2,'李必');
1 row created.
INSERT INTO "T1" VALUES (3,'檀棋');
1 row created.
COMMENT ON TABLE "T1" IS '测试表';
Comment created.
COMMENT ON COLUMN "T1"."ID" IS '身份ID';
Comment created.
COMMENT ON COLUMN "T1"."ID" IS '姓名';
Comment created.
总结
在接手一个新的测试机之后,一定要对基本的参数过一遍,踩坑的滋味实属难受。
Tank
2019.8.1