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"

相关推荐
kejijianwen2 小时前
JdbcTemplate常用方法一览AG网页参数绑定与数据寻址实操
服务器·数据库·oracle
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
高兴就好(石5 小时前
DB-GPT部署和试用
数据库·gpt
这孩子叫逆6 小时前
6. 什么是MySQL的事务?如何在Java中使用Connection接口管理事务?
数据库·mysql
Karoku0666 小时前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
码农郁郁久居人下6 小时前
Redis的配置与优化
数据库·redis·缓存
MuseLss7 小时前
Mycat搭建分库分表
数据库·mycat
Hsu_kk8 小时前
Redis 主从复制配置教程
数据库·redis·缓存
DieSnowK8 小时前
[Redis][环境配置]详细讲解
数据库·redis·分布式·缓存·环境配置·新手向·详细讲解
程序猿小D8 小时前
第二百三十五节 JPA教程 - JPA Lob列示例
java·数据库·windows·oracle·jdk·jpa