内容简介:[root@single ~]# localeLANG=en_US.UTF-8LC_CTYPE="en_US.UTF-8"
linux 环境下字符集:
[root@single ~]# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
#export NLS_LANG=american_america.zhs16gbk
windows 环境下字符集:
C:\Users\Martin>chcp
活动代码页: 936
C:>set NLS_LANG=american_america.zhs16gbk
字符集分类:
操作系统字符集
Oracle 软件字符集
Sql developer 软件带字符集,如果软件没有字符集,则使用操作系统字符集
SYS AS SYSDBA@ORCL>desc t2;
Name Null? Type
ID NUMBER(38)
NAME VARCHAR2(20)
ID 例是数字列,不需要使用字符集
NAME 列是VARCHAR2表,需要使用字符集来转换。
字符集的作用和含义:
字符编码
使用场合
数据库字符集, 以下类型要使用字符集。
1. 用来存储CHAR,VARCHAR2,CLOB,LONG等类型数据
2. 用来标示诸如表名,列名以及PL/SQL变量等
3. 用来存储 SQL 和PL/SQL程序单元等
国家字符集:
用来存储NCHAR,NVARCHAR2,NCLOB等类型数据,如果没有这些类型的数据,则不需要使用国家字符集。
SYS ASSYSDBA@ORCL>desc t3;
Name Null? Type
-----------------------------------------------------------------------------------
ID NUMBER
NAME NVARCHAR2(20)
客户端OS字符集,NLS_LANG设置,服务端OS字符集,ORACLE数据库字符集
字符集之间的关系
正确设置字符集
字符集出现问题以后的判断流程
存储的是错误的字符集
存储是的正确的字符集
Locale locale –a,chcp
字符集其实就是“字符”和“编码”的一张对照表
字符集原理:
字符集就是一个表,有两列,
左边的列是要存储的字符,比如中文字符”阮胜昌”
右边的列是一个编码,也就是计算机里面存储的数字。因为计算机里面只能存储数字,不能存储字符。
所以字符集是我们所能看到的字符与字符对应的编码的对应表。
字符集命名:
ORACLE 的字符集命令遵循以下命名规则:
<Language><bit size><encoding>
即:<语言><比特位数><编码>
比如:ZHS16GBK表示采用GBK编码格式,16位(两个字节),简体中文字符集
US7ASCII # 只能存储美国人使用的字符,26个字母,数字,运算符号(+-*/),总量不超过128个字符
ZHS16CGB231280 # 中文字符集,是国标,比较老了
ZHS16GBK # 最新的中文字符集,是字符集Zhs16CGB231280的超集,不是严格超集
AF16UTF16# 国家字符集
unicode 字符集:
AL32UTF8 # 最新的UTF8字符集(国际型企业,即有中文字符,也有其它国家的字符)
UTF8 # 比较老,字符集不全面
注:实际生产环境,如果确定数据库只是中国人用(只有中英文相关字符)的话,就采用ZHS16GBK..
数据库安装过程中,会选择确认下面两个字符集:
1. 数据库字符集:数据库需要存储多国语言选择AL32UTF8,只有中英文选择ZHS16GBK
2. 国家字符集 一般都选用AL16UTF16
NLS_LANG=<language>_<territory>.<clientcharacter set>
Language: 显示oracle消息,校验,日期命名,是用中文显示还是英文显示
Territory: 指定默认日期,数字,货币等格式
Clientcharacter set: 指定客户端将使用的字符集
例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII
AMERICAN :是语言,AMERICA是地区,US7ASCII是客户端字符集
Oracle 提供若干NLS参数定制数据库和用户以适应本地格式,例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等,可以通过查询以下数字字典或v$视图查看。
NLS_DATABASE_PARAMETERS – 显示数据库当前NLS参数取值,包括数据库字符集取值
NLS_SESSION_PARAMETERS - 显示由NLS_LANG设置的参数,或经过alter session改变后的参数值(不包括由NLS_LANG设置的客户端字符集)
NLS_INSTANCE_PARAMETE - 显示由参数文件init<SID>.ora定义的参数
V$NLS_PARAMETERS - 显示数据库当前NLS参数取值。
查看数据库字符集:用得多
SYS AS SYSDBA@ORCL>select * fromnls_database_parameters where PARAMETER='NLS_CHARACTERSET';
PARAMETER VALUE
NLS_CHARACTERSET AL32UTF8
查看国家字符集:用得少,做为数据库字符集的补充
SYS AS SYSDBA@ORCL>select * fromnls_database_parameters where PARAMETER='NLS_NCHAR_CHARACTERSET';
PARAMETER VALUE
NLS_NCHAR_CHARACTERSET UTF8
查看当前session使用的字符集:
SYS AS SYSDBA@ORCL>select * from nls_session_parameters;
SYS AS SYSDBA@ORCL>select userenv('language') fromdual;
USERENV('LANGUAGE')
-------------------------------------------------
SIMPLIFIED CHINESE_CHINA.AL32UTF8
SYS AS SYSDBA@ORCL>select nls_charset_name(to_number('0354','xxxx'))from dual;
NLS_CHARSET_NAME(TO_NUMBER('0354','XXXX'))
----------------------------------------------
ZHS16GBK
SYS AS SYSDBA@ORCL>! echo $NLS_LANG
SIMPLIFIED CHINESE_CHINA.UTF8
SYS AS SYSDBA@ORCL>select to_char(nls_charset_id('ZHS16GBK'),'xxxx')from dual;
TO_CHAR(NLS_CHARSET_ID('ZHS16GBK'),'XXXX')
------------------------------------------------------------------------------------------------------------------------------------------------------
354
查看系统支持的字符集:
SYS AS SYSDBA@ORCL>select * from V$NLS_VALID_VALUES;
sql*plus 客户端 ( 设置原则:与所在操作系统字符集一致 ):
sqlplus 没有字符集,他引用操作系统字符集
sqldeveloper 这个软件有字符集,所有不用操作系统字符集
oracle 有字符集,所有oracle不用操作系统字符集
总结 :如果oracle client如果有字符集,以软件字符集为主,不会用操作系统的字符集,所有字符集的转换都在oracle内部完成的。
客户端字符集配置:(通过配置客户端字符集,oracle就知道客户端用什么字符集编码。)
windows :一般都是gbk,即chcp结果为936
c:>set NLS_LANG=american_america.zhs16gbk
语言和地区为中文中国的话,set NLS_LANG=simplifiedchinese_china.zhs16gbk
linux :一般为utf-8,即echo $LANG 结果为en_US.UTF-8 或zh_CN.UTF-8
#export NLS_LANG=american_america.utf8
以下是错误的字符集配置:
原则:客户端的NLS_LANG配置的字符集要与客户端软件或客户端操作系统的字符集要一样
ORACLE 不管是存数据还是取数据,都要向客户端询问,对方传过来的编码是通过什么字符集转换的。
如果数据库字符集与客户端的字符集一样,ORACLE不会发生字符集转换,
如果数据库字符集与客户端的字符集不一样,ORACLE会发生这符集转换。
以下图的客户端字符集与NLS_LANG字符集不一样,这是错误的,正常的配置是NLS_LANG字符集要配置成与客户端服务器或客户端软件的字符集一样。
上图错误的原因:
客户端在 varchar2 等类型的列上存一个字符,这时在客户端会将字符转换成编码 A4 。这时将这个 A4 发送到 ORACLE 服务端,这时 ORACLE 就会问,这个 A4 编码中用什么字符集编码的,因为这时客户端的 NLS_LANG 字符集为 WE8MSWIN1252 ,所以 oracle 就认为客户端的字符集为 WE8MSWIN1252, 而不是实际的 WE8ISO8859P15 。这时 oracle 看了一下数据库的字符集是 AL32UTF8, 与客户端的字符集 WE8MSWIN1252, 所有 ORACLE 会先将 A4 这个编码用 WE8MSWIN1252 字符集转换成 A4 对应的字符。再将字符通过 AL32UTF8 转换成编码 C2A4 , ORACLE 就直接存这个转换好的编码 C2A4 。
当客户端读取数据库的字符时, ORACLE 返回以 AL32UTF8 字符集对应的编码 C2A4,ORACLE 查看到 NLS_LANG 的字符集为 WE8MSWIN1252, 与数据库的字符集不一样。所以 ORACLE 会将 C2A4 先通过 AL32UTF8 转换为字符,再用这个字符通过 WE8MSWIN1252 转换成编码。这时客户端看到的就是这个编码,但这时通过 WE8ISO8859P15 字符集解析这个编码时得不到原来的字符,这时的字符就产生的乱码。
下图的 NLS_LANG 字符集与数据库的字符集一样,与客户端的字符集不一样。
上图错误的原因:
客户端将字符编码后得到 A4 编码,这时客户端 NLS_LANG 配置为 UTF8, 而数据库的字符集也是 UTF8, 所以当将这个编码传到数据库时, ORACLE 看到客户端的 NLS_LANG 的字符集与数据库的字符集一样,所有 oracle 不会转换,而是直接将编码 A4 存入数据库。
测试:
客户端Linux,系统字符集为zh_CN.UTF-8
正确设置:
#export LANG=zh_CN.UTF-8
#export NLS_LANG=american_america.utf8
[oracle@oracle ~]$ echo $NLS_LANG
american_america.utf8
[oracle@oracle ~]$ echo $LANG
zh_CN.UTF-8
SYS AS SYSDBA@ORCL>select * from t3;
ID NAME
---------- --------------------
1 阮胜昌
commit;
查看字符对应的编码:这个编码就是oracle存储下来的。
SYS AS SYSDBA@ORCL>select id,name,dump(name,1016) fromt3;
ID NAME
---------- --------------------
DUMP(NAME,1016)
------------------------------------------------------------------------------------------------------------------------------------------------------
1 阮胜昌
Typ=1 Len=9 CharacterSet=UTF8: e9,98,ae,e8,83,9c,e6,98,8c # 以16进制显示
select id,name,dump(name,1010) from t3; # 以10进制显示
Typ=1 Len=9 CharacterSet=UTF8:233,152,174,232,131,156,230,152,140
select id,name,dump(name,1008) from t3; # 以8进制显示
Typ=1 Len=9 CharacterSet=UTF8:351,230,256,350,203,234,346,230,214
错误配置1:
[oracle@oracle ~]$ echo $LANG
en_US.UTF-8
[oracle@oracle ~]$ echo $NLS_LANG
SIMPLIFIED CHINESE_CHINA.UTF8
SYS AS SYSDBA@ORCL>select id,name from t3;
ID NAME
---------- --------------------
1 껨 莜
错误配置2:
#export NLS_LANG=american_america.zhs16gbk
select dump(' 靖宇',1016) from dual;
insert into t2 values (2,' 靖宇');
commit;
注意:字符集设置错误导致库中存储的就是错误的编码,这个几乎是不可逆的`一定要慎重仔细设置好字符集。
查看字符:阮胜昌字符正确的编码:
SYS AS SYSDBA@ORCL>select dump(' 阮胜昌',1016) from dual;
DUMP(' 阮胜昌',1016)
Typ=96 Len=9 CharacterSet=AL32UTF8:e9,98,ae,e8,83,9c,e6,98,8c
insert into t2 values (2,' 阮胜昌');
commit;
服务器上oracle字符集
如何确定当前字符集设定,何时可以更改字符集。
SYS AS SYSDBA@ORCL>select userenv('language') fromdual;
USERENV('LANGUAGE')
AMERICAN_AMERICA.AL32UTF8
查看系统的字符集:
select * from v$nls_parameters;
了解超集,严格超集的概念,确定是否可以更改字符集。Oracle不建议后期更改数据库字符集!
服务器操作系统字符集(暂时忽略)
ps:
1. 因为sql*plus 本身没有字符集,依赖于所在操作系统的字符集,而在远端 linux 上的oracle也是无法直接访问到windows上的字符集,所以依靠sql*plus的NLS_LANG设置来辨别。
2. 因为oracle软件本身有字符集,当软件有自己的字符集时,就不用操作系统的字符集,所以服务器操作系统字符集的因素可以暂时忽略。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- oracle查看字符集 修改字符集
- Oracle 字符集实验
- go基础库之解码非Unicode字符集中的字符串
- [MySQL]支持 emoji(字符集问题)
- 带你5分钟读懂MySQL字符集设置
- Docker下mysql设置字符集的方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
风口上的汽车新商业
郭桂山 / 人民邮电出版社 / 59
本书从互联网+汽车趋势解析、汽车电商困局突围策略、汽车后市场溃败求解等三个篇章详细阐述了作者的观察与思考,当然更多的还是作者在汽车电商行业的实践中得出的解决诸多问题的战略策略,作者站在行业之巅既有战略策略的解决方案,同时也有战术上的实施细则,更有实操案例解析与行业大咖访谈等不可多得的干货。当然,作者一向追崇的宗旨是,书中观点的对错不是最重要的,重在与行业同仁探讨,以书会友,希望作者的这块破砖头,能......一起来看看 《风口上的汽车新商业》 这本书的介绍吧!