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"

相关推荐
workflower1 小时前
PostgreSQL 数据库优化
数据库·团队开发·数据库开发·时序数据库·数据库架构
计算机毕设VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue服装商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·课程设计
WX-bisheyuange3 小时前
基于Spring Boot的智慧校园管理系统设计与实现
java·大数据·数据库·毕业设计
JavaGuide4 小时前
对标MinIO!全新一代分布式文件系统诞生!
数据库·后端
快乐非自愿4 小时前
数据库如何处理大量的交易流水记录
数据库·oracle
IvorySQL4 小时前
瀚高硬核助力 PG 社区:Postgres 19 迎来并行 TID 范围扫描,速度提升 3 倍
数据库·postgresql·开源
ServBay4 小时前
MongoDB 的文档模型与 CRUD 实战
数据库·后端·mongodb
ITMr.罗4 小时前
深入理解EF Core更新机制(开发中因为省事遇到的问题)
服务器·数据库·c#·.net
梁萌4 小时前
MySQL索引的使用技巧
数据库·mysql·索引·b+tree
x10n95 小时前
OceanBase 参数对比工具 附源码
数据库·vscode·oceanbase·腾讯云ai代码助手