测试环境:数据库服务器字符集为AL32UTF8
操作系统字符集为ZHS16GBK
创建测试表:
create table CHARSETTBL ( CLIENTCHARSET VARCHAR2(30),--nls_lang DES VARCHAR2(30) )
STEP1:
设置NLS_LANG=ZHS16GBK,然后在SQLPLUS中插入记录
INSERT INTO CHARSETTBL VLAUES('sqlpluszhs16gbk','中国');
STEP2:
重新设置NLS_LANG=AL32UTF8,重开一个SESSION,在SQLPLUS中插入记录
INSERT INTO CHARSETTBL VLAUES('sqlplusutf8','中国');
STEP3:
安装PLSQL DEVELOPER8.0,打开帮助可看到
Character Sets
Character size: 4 byte(s)
CharSetID: 873
NCharSetID: 2000
Unicode Support: True
NLS_LANG: AMERICAN_AMERICA.AL32UTF8
NLS_CHARACTERSET: AL32UTF8
NLS_NCHAR_CHARACTERSET: AL16UTF16
然后再PLSQL DEVELOPER8.0中插入记录
INSERT INTO CHARSETTBL VLAUES('plsqlutf8','中国');
STEP4:
重新设置NLS_LANG=ZHS16GBK并重新安装PLSQL DEVELOPER8.0,因为改变注册表中的NLS_LANG值并不会影响PLSQL8.0中的NLS_LANG设置,目前也没有找到更好的方法来修来,只有重装,然后装好第一次的时候它会去加载注册表中的NLS_LANG值。
然后继续在PLSQL8.0中插入记录
INSERT INTO CHARSETTBL VLAUES('plsqlzhs16gbk','中国');
查看结果
SQL> select clientcharset,dump(des,1016) from charsettbl;
CLIENTCHARSET DUMP(DES,1016)
------------------------------ --------------------------------------------------------------------------------
plsqlutf8 Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd
plsqlzhs16gbk Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd
sqlpluszhs16gbk Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd
sqlplusutf8 Typ=1 Len=4 CharacterSet=AL32UTF8: d6,d0,b9,fa
可以看到plsqlutf8对应的字符编码仍然是数据库字符集的编码形式,而用SQLPLUS插入时,因为NLS_LAGE和数据库服务器字符集一样,所以ORACLE并没有做字符转换,直接插入了操作系统的字符集编码,但PLSQL8.0确做了一次转换。
7.0版本和SQLPLUS一致,这个新特性很容易迷惑人哈。
并且在8.0中做如下查询显示如下
SQL> select * from charsettbl;
CLIENTCHARSET DES
------------------------------ ------------------------------
plsqlutf8 中国
plsqlzhs16gbk 中国
sqlpluszhs16gbk 中国
sqlplusutf8 中国
在SQLPLUS中做同样查询显示如下
SQL> select * from charsettbl;
CLIENTCHARSET DES
------------------------------------------------------------ ----
plsqlutf8 中国
plsqlzhs16gbk 中国
sqlpluszhs16gbk 中国
sqlplusutf8 ???
可以看出PLSQL8.0中对查询结果也做了字符集的自动转换,而SQLPLUS却没有。