# Oracle中nls_characterset与nls_nchar_characterset的设置及其影响
在众多的资料中,仅是说了
nls_characterset数据库字符集 nls_nchar_characterset数据库国家字符集或者国际化设置字符集
nls_characterset与数据库中char、varchar blob类型的属性字段有密切的关系
nls_nchar_characterset与nchar、nvarchar2属性字段类型相关

  偶然的一个机会,让我怀疑,虽然,还没有查到确切的文献依据,nls_characterset Oracle数据库字符集的设置,对C/S结构下的数据库访问应用有比较大的影响。在这种结构中存在一个不起眼的细节,即在C/S结构下的数据库访问中,客户端经常将要执行的SQL语句发送到数据服务器端DBMS去执行,而这个SQL语句必定是要按照一定的字符集进行编码的。发送SQL语句编码的这个字符集或者是约定或者是客户端和服务器端协商得到的。但是,不管这个字符集是如何确定的,这个对我们要说明的问题影响不是太大,我们所需假设的即这个发送到服务器端执行的SQL语句是按照某种字符集编码。
   一般情况下,服务器端只要对客户端发送过来的SQL语句解码正确,我们是不会发现其有异常的。但是,在国际化数据库应用下或扩展已有的数据库应用成为国际化版本时,如果nls_nchar_characterset设置欠乏考虑,就会出现写入数据库的数据,在字节级的信息就是乱码,更况论其显示值了,那就更是错误百出了,因为根基就是错的!观察表属性的字节级信息,在oracle里是通过dump(columnName,16)观察。
   例如,在某个数据库中nls_nchar_characterset的设置为GBK,为了应付国际化,数据库应用对数据库表中可能包含非GBK字符集范围的列,全部定义为nachar或者其他国际化属性类型。按照通常网上资料或者简明Oracle说明书,这样的设置应该是没有问题,但是,在这里再次强调下,我们出问题的不起眼的源头,某些C/S结构下的数据库访问,客户端是通过发送SQL语句到数据库执行的方式,达到访问数据库的效果。这样架构下,就会牵扯数据库服务器端,会以何种字符集,让DBMS统一看待、处理SQL语句呢?我想,这里Oracle数据库系统,可能会简单地以ASCII字符集处理SQL关键字、分割符,而以nls_characterset设定的字符集应对SQL语句中非关键字,例如查询条件、赋值等。或者它会以更简单、明快的处理方案,将客户端不管以何种编码过来的SQL语句串都转换到nls_characterset设定的字符集,统一进入SQL后续执行的核心区。不管Oracle可能会采用这两种可能的哪一种,对于客户端发送过来的SQL语句中非SQL规范关键字范畴的部分,数据库服务器端可能都会采用nls_characterset设定的字符集在后期进行处理,这样,在后面的继续处理中就会发生问题。
  关于Oracle客户端访问程序,其发送过来的SQL语句的字符集可以和Oracle数据库nls_characterset设置是不同的,而不是像有些网上文档说的两者之间要保持严格相同。实际上,Oracle可能提供了对客户端不同编码格式的数据进行解码的过程,但是,Oracle解码完成后的终点基座、最终的目标可能是Oracle自身设置的nls_characterset数据库字符集。

  呵呵,在这里声明一下,我也是以概念逻辑上的推测、猜度别人,而非查到第一手的关键文献资料。但是,上面所有基于猜测,都是某次Oracle故障后,自己找出的唯一比较近乎合理的解释!我也没有强求这个文档的真金白银的价值,只希望对大家有用,提供一个可能的新视角,对其价值看做仅作参考即可。很多时候,我喜欢的编程生活是,不需要懂得太多的技术细节,只需要知道它的概念逻辑即可,即其可能的实现是什么就可以了!懂得太深,会耗去很多宝贵的时间的。而且,只要你懂得其概念逻辑和模型后,后面的全部只是时间问题,也和具体实现语言也没有太大的关系,这就是概念逻辑的优势,在没有硝烟的战场是取得胜利。在这里将这次的故障总结写入博客,也是希望有人能够指出其中纰露 :)

 基于上面的所有分析,我们就可以看出来,如果客户端JDBC访问以utf-8方式将要在服务器端执行的SQL语句发送到服务器端,而其insert或者update的值域信息里面含有非nls_characterset,这个时候,请注意,字节级的乱码就出现了。因为两个字符集间utf-8<-->nls_characterset的映射关系,在事实上确实也并不是完全包含的。当然,你可以严格限定你的客户端发送到服务器端的utf-8字符编码,就是nls_characterset的一个子集,这样你也就不会出现乱码问题。但是,当你扩展你这个数据库应用,来应付更多的国际化的时间,你一定要小心了。虽然,Oracle JDBC驱动为了处理国际化的问题,已经将自己发送到服务器端的SQL语句的字符编码按照utf-8字符集进行实施,它可以是被认为近乎无限的语言处理能力,但是,你的数据库服务器端,在Oracle9i版本,未必有能力能够处理,因为它可能按照nls_characterset字符集的设定去处理客户端发送过来的SQL语句。不过,实际上Oracle可以作的更多,它可以进一步分析,如果SQL语句中含有nchar的属性列的处理,就不能以nls_characterset来处理SQL中的"值域“信息,我们程序员的控制力是还有很大空间的 :)。从故障的各方面分析来看,在Oracle9i版本好似还没有这样的特殊智能。

 验证我这个推测的一个佐证是查看V$SQLArea视图的定义,可以看到其SQL_TEXT列的类型为varchar(1000),即这个号称可以共享SQL语句的缓存统计表,处理客户端发送过来的SQL语句,其存储的字符集为nls_characterset!

欢迎大家指正!

nls_characterset Oracle数据库的定海神针相关推荐

  1. ORACLE数据库NLS_CHARACTERSET和NLS_NCHAR_CHARACTERSET区别

    使用Select * from nls_database_parameter去查看的字符集,发现查到两个字符集,NLS_CHARACTERSET 和NLS_NCHAR_CHARACTERSET.如下: ...

  2. 修改oracle数据库默认时间格式

    oracle数据库默认的时间格式只能精确到天(DD-MON-RR),在实际工作环境中,开发程序通常需要取得精确到秒的时间值,经查询资料在oracle中修改时间值的方式大致可以分为以下几种: 1.临时修 ...

  3. 关于Oracle数据库19c中的关键字和保留字的说明

    关于Oracle数据库中的关键字和保留字的说明 官方文档节选: ​ You cannot use Oracle SQL reserved words as nonquoted identifiers. ...

  4. oracle数据库简单操作

    导入某用户所有表和数据: imp sgp/sgp@192.168.0.99:1521/orcl file=sgp20161025.dmp full=y 导出指定表及数据: exp sgp/sgp@19 ...

  5. perl unload gbk oracle 数据库

    perl unload gbk Oracle 数据库use Encode; if ( $#ARGV < 0 ){print "请输入一个文件\n";exit(-1);}$va ...

  6. Oracle数据库之过滤和排序

    oracle安装参照: Oracle数据库之安装教程 Oracle数据库总结: Oracle数据库之基本查询 Oracle数据库之单行函数 Oracle数据库之多行函数 Oracle数据库之多表查询 ...

  7. oracle转64编码,[转]将oracle数据库的编码变成utf-8

    1.改客户端字符集:通过WINDOWS的运行菜单运行Regedit,修改注册表 Start -> Run -> Rededit Under registry Editor - > H ...

  8. 13 Oracle数据库开发与设计入门篇

    Oracle数据库SQL语言基础 SQL(Structured Query Language,结构化查询语言)语言是一种在关系数据库中定义和操纵数据的标准语言,是用户与数据库之间进行交流的接口.SQL ...

  9. oracle命令行查看编码,Oracle数据库查看编码和修改编码

    首先查看oracle数据库的编码 SQL> select * from nls_database_parameters where parameter ='NLS_CHARACTERSET'; ...

最新文章

  1. C++ explicit 的用法,就是必须显示调用
  2. XML 命名空间(XML Namespaces)
  3. 阿里云能耗宝即将发布,助力中小企业绿色升级,参与碳中和万亿市场
  4. 九.激光SLAM框架学习之LeGO-LOAM框架---速腾Robosense-16线雷达室外建图和其他框架对比、录包和保存数据
  5. [转帖] IPsec相关知识 --未知来源
  6. 奇奇怪怪的东西(1)
  7. Autolisp:利用AuoCAD之Lisp编程案例之智能加工齿轮的演示程序
  8. 计算机怎么打开网络共享,如何开启Window7的媒体流共享(开启电脑 DLNA 共享)...
  9. 浅淡 Apache Kylin 与 ClickHouse 的对比
  10. 金蝶显示服务器许可,金蝶K3服务器分配许可数已经全部使用,无法建立新的连接怎么办...
  11. ubuntu 改屏幕分辨率命令_ubuntu 修改分辨率为自定义分辨率
  12. ORACLE US7ASCII编码 读取时乱码问题
  13. An error occurred while attempting to sign 处理方法
  14. 对话《旅行青蛙》制作团队:游戏就是将现实中的不可能变为可能 | 覆盖客户全生命周期管理,神州云动六朵云来袭
  15. B端产品客户画像的一点感悟
  16. 爬虫学习笔记-scrapy框架介绍
  17. python barrier_Python多线程Barrier(障碍对象) 雷子
  18. 苹果手机来电归属地_工信部 : 暂未出台取消手机号码归属地政策!
  19. HTTPS原理解析-转
  20. 情人节程序员用HTML网页表白【做我女朋友】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript

热门文章

  1. ASP.NET DataList嵌套实现评论效果
  2. CMS用通用图片轮换flash幻灯片播放器:Bcastr3和Bcastr4
  3. C语言有小数乘法,十道小数乘小数的乘法竖式计算并有答案
  4. Touch Bar长按会出现一个圆圈,同时屏幕上同时出现Touch Bar的图像,取消该功能的解决方法
  5. Hive访问权限控制
  6. 回顾经典电影星舰战队I have not been to Paradise[图]
  7. buuctf逆向simple rev
  8. 隐私浏览器 Tor Browser 8.0.7 发布,安全更新版本
  9. Java获得腾讯QQ在线状态(.net webservice)
  10. 流浪动物领养公益系统