[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]
解决在 sqlplus 命令行中插入 Oracle 中文数据报错及乱码问题
错误信息:在 sqlplus 命令行中执行下述插入语句,报 ORA-01756: quoted string not properly terminated ,以及乱码问题。
SQL> insert into test(id,name) values (6,'Oracle关系型数据库');
ERROR:
ORA-01756: quoted string not properly terminated
问题原因:可将上述两个问题合并到一起解决,问题1解决了,问题2自然也就解决了。前者是由于在 sqlplus 命令行中插入中文数据时,由于使用的 XSHELL 或者 MobaXterm 终端(作者环境
)的客户端字符集不一致,插入中文时会经行转码,导致某些字符串可能转成中文符号导致sql出现错误,后者则sqlplus客户端使用的编码和服务器端编码不一致导致乱码。
问题解决:
1.查看数据库服务端字符集,客户端编码以及当前会话的字符集,NLS_LANG 的组成规则为
NLS_LANGUAGE_NLS_TERRITORY.NLS_CHARACTERSET
。
-- 1.查看数据库服务端字符集
SELECT userenv('language') FROM dual; -- AMERICAN_AMERICA.ZHS16GBK
SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER IN ('NLS_LANGUAGE', 'NLS_TERRITORY', 'NLS_CHARACTERSET');
-- NLS_CHARACTERSET ZHS16GBK
-- NLS_TERRITORY AMERICA
-- NLS_LANGUAGE AMERICAN-- 2.查看sqlplus客户端编码
SELECT * FROM V$NLS_PARAMETERS WHERE PARAMETER IN ('NLS_LANGUAGE', 'NLS_TERRITORY', 'NLS_CHARACTERSET');
-- NLS_LANGUAGE AMERICAN
-- NLS_TERRITORY AMERICA
-- NLS_CHARACTERSET ZHS16GBK-- 3.查看当前会话的字符集
SELECT * FROM nls_session_parameters WHERE parameter in ( 'NLS_LANGUAGE','NLS_TERRITORY','NLS_CHARACTERSET');
-- NLS_LANGUAGE AMERICAN
-- NLS_TERRITORY AMERICA
2.修改 MobaXterm 终端工具字符集,并将其设置为
gbk
, 重新打开终端在MobaXterm终端上执行export LANG=zh_CN.GBK
, 需根据数据库实际编码调整。
3.使用 MobaXterm 连接的是远程服务器,若远程服务器存在字符编码问题,我们还可以在远程服务器上修改系统字符集。
declare -x LANG="zh_CN.gbk"
declare -x LC_ALL="zh_CN.gbk"
4.最后远程服务器设置 sqlplus 客户端字符集,使其与服务端保持一致。
Linux 环境:执行
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
命令,或者将此命令放于 Oracle 用户的Shell启动.bash_profile
中,并执行source ~/.bash_profile
使之生效。Windows 环境:计算机->属性->高级系统设置->环境变量->新建 NLS_LANG 变量 ,变量值设置为
AMERICAN_AMERICA.ZHS16GBK
或者 执行set nls_lang=american_america.ZHS16GBK
命令。
验证配置:
set headingoff
set line 300 pagesize 999
truncatetabletest; -- 清空表数据
insertintotest(id,name) values (1, '关系型数据库');
insertintotest(id,name) values (2, 'MySQL');
insertintotest(id,name) values (3, 'Oracle');
insertintotest(id,name) values (4, '"达梦数据库"');
insertintotest(id,name) values (5, '中文测试');
updatetestsetname = '"DM达梦数据库"'whereid=5;-- 若然不行,则使用最终大法绑定变量来插入中文数据
VARIABLE v_id NUMBER;
VARIABLE v_name VARCHAR2(100);
EXEC :v_id := 6; -- PL/SQL 过程已成功完成。
EXEC :v_name := '中文测试'; -- PL/SQL procedure successfully completed.
INSERTINTOtest(id,name) VALUES (:v_id,:v_name);
1 row created.-- 测试结果:
SQL> select * fromtest;1 关系型数据库2 MySQL3 Oracle5 "DM达梦数据库"4 "达梦数据库"6 中文测试
6 rows selected.
SQL> commit;
Commit complete.
知识扩展:使用 Navicat Premium 连接 Oracle 数据库,在 Navicat Premium 中插入中文数据在 sqlplus 命令行中查询是乱码,解决办法如下:编辑 Oracle 连接配置,设置客户端字符集 为 ZHS16GBK
编码默认为 65001 (UTF-8)
,保存后重新连接即可, 插入两条中文数据测试。
“苦海无边,学海无涯”
关注作者学习更多实用DBA实用技巧!
若文章写得不错,不要吝惜手中转发,点赞、在看,若有疑问的小伙伴,可在评论区留言你想法哟💬!
温馨提示:作者最近10年的工作学习笔记(涉及网络、安全、运维、开发),需要学习实践笔记的看友,可添加作者账号[WeiyiGeeker],当前价格¥199,除了获得从业笔记的同时还可进行问题答疑以及每月远程技术支持,希望大家多多支持,收获定大于付出!
如果此篇文章对你有帮助,请你将它转发给更多的人!
学习推荐 往期文章