oracle读写时相关字符集详解

服务器端操作系统(Oracle linux)字符集

服务器端数据库字符集

客户端操作系统(Oracle linux)字符集

客户端工具sqlplus字符集

结论1:客户端工具sqlplus的会话,使用的字符集,是数据库字符集。如果客户端用户的env环境变量设置了NLS_LANG变量,则优先使用这个变量指定的字符集。

结论2:通过客户端工具往数据库写入内容时,存储到表中的字段是按照写入时客户端工具的字符集编码进行存储的。

结论3:操作系统的环境变量LANG中字符集,对客户端工具执行sql返回的数据结果如何显示没有影响。

环境字符集

服务器

env命令查看服务器操作系统的字符集

数据库字符集

SELECT parameter, value

FROM NLS_DATABASE_PARAMETERS

WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

或者

SELECT * FROM V$NLS_PARAMETERS

WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

查看数据库字符集(NLS_CHARACTERSET)、国家字符集(NLS_NCHAR_CHARACTERSET)设置。

客户端

env命令查看客户机的字符集

使用的服务器上的客户端工具,sqlplus,所以客户端机器就是服务器机器。字符集同上。

启动sqlplus,默认会话的NLS参数如下

SELECT * FROM NLS_SESSION_PARAMETERS;

使用命令修改机器当前会话的环境变量

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8" 可

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK" 不可

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF-8" 不可

export LANG=zh_CN.UTF8 不可

修改前,之前用sqldeveloper插入的中文显示乱码

机器会话env环境变量如下所示,已经发生变化

登录sqlplus,查看会话环境变量

实验操作

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

客户端工具字符集

默认

即当前会话字符集,登录客户端,执行SELECT * FROM NLS_SESSION_PARAMETERS;

如前截图所示,NLS_LANGUAGE、NLS_TERRITORY,推测,客户端工具sqlplus会话默认使用数据库字符集。

进一步验证,调整数据库字符集,再执行SELECT * FROM NLS_SESSION_PARAMETERS;

截图如下,已经发生了变化。

alter system set NLS_LANGUAGE='SIMPLIFIED CHINESE' scope=spfile;

alter system set NLS_TERRITORY='CHINA' scope=spfile;

SELECT * FROM V$NLS_PARAMETERS

重新执行查看sqlplus会话参数,与已经更改的数据库字符集一致

SELECT * FROM NLS_SESSION_PARAMETERS;

使用如下命令,再改回验证,完全没问题。

alter system set NLS_LANGUAGE='AMERICAN' scope=spfile;

alter system set NLS_TERRITORY='AMERICA' scope=spfile;

注意,查看调整结果时,要开启新的会话窗口,才能看到最新的调整结果。

环境变量

当sqlplus所在机器的环境变量中包含NLS_LANG环境变量时,sqlplus会话会优先获取变量值,可以查询NLS_SESSION_PARAMETERS进行验证。

设置环境变量

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"

设置前,SELECT * FROM NLS_SESSION_PARAMETERS;

调整

字符集不一致时

客户端两个窗口,一个字符集是UTF8(A)、一个字符集是ZHS16GBK(B),数据库字符集是ZHS16GBK。A和B分别向数据库中写入一条中文记录,然后A和B再读取该表中刚写入的中文记录。

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"

sqlplus test2/test2

insert into ttest values('哈哈');

commit;

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

sqlplus test2/test2

insert into ttest values('嘻嘻');

commit;

从以上可以看出,向数据库表中写入字段内容时,是按照客户端当时的会话字符集向数据库写入的,而与数据库字符集无关。而客户端会话读取数据库字段时,要与存储时的字符集相符,否则乱码。

字符集处理函数

dump函数

参照

https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions108.htm#i78230

select dump(c1,1016) from ttest;

该函数返回的字符集,是当前数据库的字符集,并不是存储该字段时的字符集。

客户端会话UTF8字符集,哈哈是客户端会话字符集为UTF8时写入

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"

客户端会话ZHS16GBK字符集,嘻嘻是客户端会话字符集为ZHS16GBK时写入

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

相关推荐
ClouGence1 小时前
CloudDM 新增支持 GaussDB 与 openGauss:国产数据库管理更高效
数据库·sql·ci/cd
sukalot1 小时前
window显示驱动开发—在混合系统中使用跨适配器资源
数据库·驱动开发·音视频
洛卡卡了1 小时前
数据库加密方案实践:我们选的不是最完美,但是真的够用了。
数据库·后端·面试
幽络源小助理1 小时前
MySQL实战优化高手教程 – 从架构原理到生产调优
数据库·mysql·架构
Runing_WoNiu2 小时前
Redis主从架构、哨兵模式及集群比较
数据库·redis·架构
考虑考虑3 小时前
postgressql更新时间
数据库·后端·postgresql
甄超锋3 小时前
python sqlite3模块
jvm·数据库·python·测试工具·django·sqlite·flask
HMBBLOVEPDX4 小时前
MySQL的锁:
数据库·mysql
数据皮皮侠5 小时前
最新上市公司业绩说明会文本数据(2017.02-2025.08)
大数据·数据库·人工智能·笔记·物联网·小程序·区块链
小云数据库服务专线6 小时前
GaussDB数据库架构师修炼(十六) 如何选择磁盘
数据库·数据库架构·gaussdb