Oracle nvarchar2存儲特殊字符亂碼問題


 

Oracle nvarchar2存儲特殊字符亂碼問題

 

這個問題研究了一天多,終於搞定了。

起因是業務需要存特殊字符'ø'到varchar2的字段中出現亂碼,因為數據庫字符集是ZHS16GBK。

簡單測試了下,像'ø'之類的特殊。由於國家字符集是AL16UTF16,准備用nvarchar2(nvarchar2用的是國家字符集)存儲特殊字符。

但是測試環境測試結果是就算用nvarchar2存,還是有亂碼的情況。

重現如下:

[oracle@zkm ~]$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
[oracle@zkm ~]$ echo $NLS_LANG
AMERICAN_AMERICA.AL32UTF8

11:22:28 SYS@zkm(451)> select userenv('language') from dual;

USERENV('LANGUAGE')
--------------------------------------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

Elapsed: 00:00:00.01
11:22:06 SYS@zkm(451)> create table zkm ( name1 varchar2(20),name2 nvarchar2(20));

Table created.

Elapsed: 00:00:01.39

11:30:12 SYS@zkm(451)> select * from NLS_DATABASE_PARAMETERS;

PARAMETER                                          VALUE
-------------------------------------------------- --------------------------------------------------
NLS_LANGUAGE                                       AMERICAN
NLS_TERRITORY                                      AMERICA
NLS_CURRENCY                                       $
NLS_ISO_CURRENCY                                   AMERICA
NLS_NUMERIC_CHARACTERS                             .,
NLS_CHARACTERSET                                   ZHS16GBK
NLS_CALENDAR                                       GREGORIAN
NLS_DATE_FORMAT                                    DD-MON-RR
NLS_DATE_LANGUAGE                                  AMERICAN
NLS_SORT                                           BINARY
NLS_TIME_FORMAT                                    HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT                               DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT                                 HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT                            DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY                                  $
NLS_COMP                                           BINARY
NLS_LENGTH_SEMANTICS                               BYTE
NLS_NCHAR_CONV_EXCP                                FALSE
NLS_NCHAR_CHARACTERSET                             AL16UTF16
NLS_RDBMS_VERSION                                  11.2.0.4.0

20 rows selected.

Elapsed: 00:00:00.00
11:31:18 SYS@zkm(451)> insert into zkm values ('ø','ø');

1 row created.

Elapsed: 00:00:00.00
11:31:21 SYS@zkm(451)> commit;

Commit complete.

Elapsed: 00:00:00.00
11:31:26 SYS@zkm(451)> select * from zkm;

NAME1      NAME2
---------- ----------
?         ?           (這里是中文問號)

Elapsed: 00:00:00.00

 

 

比對中文問號和英文問號:

14:19:01 SYS@zkm(451)> select dump('?',1016) from dual union all select dump('',1016) from dual union all select dump('ø',1016) from dual;

DUMP('?',1016)
---------------------------------------------------------------------------------------------------------------------------
Typ=96 Len=1 CharacterSet=ZHS16GBK: 3f
Typ=96 Len=2 CharacterSet=ZHS16GBK: a3,bf
Typ=96 Len=2 CharacterSet=ZHS16GBK: a3,bf

Elapsed: 00:00:00.01

 

 

也就是說,在ZHS16GBK下,中文"?"和"ø"最后成了一樣的效果,也就是"ø"亂碼了。

這個很好理解,Linux OS將UTF8類型的"ø"通過sqlplus這個客戶端送進去數據庫中,然后數據庫通過NLS_LANG環境變量了解到進來的"ø"是UTF8編碼的,於是通過比對UTF8編碼表和GBK編碼表對應的"ø",將UTF8編碼的"ø"轉換成GBK的"ø"。

由於GBK不支持特殊字符"ø",在GBK編碼表中不存在對應的編碼,於是使用GBK編碼表中的中文"?"編碼替代,通過上邊的dump可知為a3bf,這個就是亂碼的原因。

我們可以dump表zkm的name1,由於name2字段為nvarchar類型,該類型不使用數據庫字符集ZHS16GBK,而是使用國家字符集AL16UTF16,因此有如下結果:

14:38:24 SYS@zkm(87)> select dump(name1,1016) name1,dump(name2,1016) name2 from zkm;

NAME1                                              NAME2
-------------------------------------------------- --------------------------------------------------
Typ=1 Len=2 CharacterSet=ZHS16GBK: a3,bf           Typ=1 Len=2 CharacterSet=AL16UTF16: ff,1f

Elapsed: 00:00:00.00

 

 

可以知道,將"ø"insert進去表的name1,name2字段,確實變成了中文的"?" ,都是'a3bf'。

不過問題是nvarchar類型用的是AL16UTF16,為啥存不了"ø"??


網上找資料才發現,要通過加N告訴這個特殊字符是Unicode字符才行。

用法參考:

http://www.orafaq.com/wiki/NVARCHAR2

http://www.orafaq.com/wiki/NCHAR

於是:

15:35:30 SYS@zkm(1398)> select dump(N'?',1016) from dual union all select dump(N'',1016) from dual union all select dump(N'ø',1016) from dual;

DUMP(N'?',1016)
--------------------------------------------------------------------------------
Typ=96 Len=2 CharacterSet=AL16UTF16: 0,3f
Typ=96 Len=2 CharacterSet=AL16UTF16: ff,1f
Typ=96 Len=2 CharacterSet=AL16UTF16: ff,1f

Elapsed: 00:00:00.00
15:35:39 SYS@zkm(1398)> delete zkm;

1 row deleted.

Elapsed: 00:00:00.01
15:35:44 SYS@zkm(1398)> insert into zkm values ('ø',N'ø');

1 row created.

Elapsed: 00:00:00.00
15:36:05 SYS@zkm(1398)> commit;

Commit complete.

Elapsed: 00:00:00.00
15:36:44 SYS@zkm(1398)> select * from zkm; 

NAME1      NAME2
---------- ----------
?         ?

Elapsed: 00:00:00.00

 

 

加了N后還是發現,AL16UTF16下,中文"?"和"ø"還是一樣的。

難道AL16UTF16不支持字符"ø"??不可能啊。

於是在新建了一個字符集為AL32UTF8的庫,做上邊同樣建表的操作,然后插入數據,無論是varchar或者nvarchar都不會亂碼啊,部分如下操作:

SQL> select dump(N'?',1016) from dual union all select dump(N'',1016) from dual union all select dump(N'ø',1016) from dual;

DUMP(N'?',1016)
------------------------------------------
Typ=96 Len=2 CharacterSet=AL16UTF16: 0,3f
Typ=96 Len=2 CharacterSet=AL16UTF16: ff,1f
Typ=96 Len=2 CharacterSet=AL16UTF16: 0,f8

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8

SQL> select dump(N'?',1016) from dual union all select dump(N'',1016) from dual union all select dump(N'ø',1016) from dual;

DUMP(N'?',1016)
------------------------------------------
Typ=96 Len=2 CharacterSet=AL16UTF16: 0,3f
Typ=96 Len=2 CharacterSet=AL16UTF16: ff,1f
Typ=96 Len=2 CharacterSet=AL16UTF16: 0,f8

SQL> select unistr('\00F8') from dual;

UNIS
----
ø

 

從這個實驗基本能夠確定,Oracle將特殊字符"ø"存入數據庫的時候,是先通過存為數據庫字符集ZHS16GBK,然后再通過ZHS16GBK轉為國家字符集AL16UTF16。

由於轉ZHS16GBK的時候已經亂碼,再次轉AL16UTF16的時候就有問題了。

新庫已經證明了國家字符集可以存該特殊字符了。

 

那么到底如何能夠將特殊字符存進去nvarchar而不亂碼,百度找不到於是只能MOS搜了,果然找到了..
實際上,環境變量ORA_NCHAR_LITERAL_REPLACE默認值為false,該變量表示任何從客戶端傳過來的NCHAR類型的字符先轉換為數據庫字符集,再轉換為國家數據庫字符集,而把該參數設為true后,從客戶端傳過來的NCHAR類型的字符直接轉換為國家字符集存儲,因此要想正確存儲NCHAR字符集,最好得把該參數設為TRUE。

[oracle@zkm ~]$ export ORA_NCHAR_LITERAL_REPLACE=true
15:37:07 SYS@zkm(99)> delete from zkm;

1 row deleted.

Elapsed: 00:00:00.00
15:37:14 SYS@zkm(99)> insert into zkm values ('ø',N'ø');

1 row created.

Elapsed: 00:00:00.00
15:37:19 SYS@zkm(99)> commit;

Commit complete.

Elapsed: 00:00:00.00
15:37:22 SYS@zkm(99)> col name1 for a10
15:37:27 SYS@zkm(99)> col name2 for a10
15:37:27 SYS@zkm(99)> select * from zkm;

NAME1      NAME2
---------- ----------
?         ø

Elapsed: 00:00:00.00

 

由於name1為varchar類型本身不支持特殊字符亂碼是正常的,而name2為nvarchar現在已經正常存取了。

 

開啟會話,做10046。

執行sql,對應trace信息:

insert into zkm values ('ø',N'ø');
對應的trc信息:
*** 2021-08-18 16:03:01.812 WAIT #140175898804800: nam='SQL*Net message from client' ela= 24006178 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1629273781812848 CLOSE #140175898804800:c=9,e=9,dep=0,type=1,tim=1629273781812992 ===================== PARSING IN CURSOR #140175898795576 len=38 dep=0 uid=0 oct=2 lid=0 tim=1629273781814001 hv=1357752502 ad='ce798418' sqlid='fj1m2tx8fva5q' insert into zkm values ('U'\00F8') END OF STMT PARSE #140175898795576:c=941,e=950,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1629273781813995 EXEC #140175898795576:c=256,e=256,p=0,cr=1,cu=2,mis=0,r=1,dep=0,og=1,plh=0,tim=1629273781814387 STAT #140175898795576 id=1 cnt=0 pid=0 pos=1 obj=0 op='LOAD TABLE CONVENTIONAL (cr=1 pr=0 pw=0 time=195 us)' WAIT #140175898795576: nam='SQL*Net message to client' ela= 3 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1629273781814475 *** 2021-08-18 16:04:06.396 WAIT #140175898795576: nam='SQL*Net message from client' ela= 64582323 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1629273846396824 CLOSE #140175898795576:c=9,e=9,dep=0,type=0,tim=1629273846397035

 

select N'ø' from dual;

對應的trc信息:
PARSING
IN CURSOR #140175898795576 len=25 dep=0 uid=0 oct=3 lid=0 tim=1629273846398341 hv=1602785773 ad='f1c07ee8' sqlid='9rgvrkjgsj4gd' select U'\00F8' from dual END OF STMT PARSE #140175898795576:c=1197,e=1208,p=0,cr=0,cu=2,mis=1,r=0,dep=0,og=1,plh=1388734953,tim=1629273846398339 EXEC #140175898795576:c=28,e=28,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629273846398525 WAIT #140175898795576: nam='SQL*Net message to client' ela= 2 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1629273846398588 FETCH #140175898795576:c=13,e=13,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=1388734953,tim=1629273846398649 STAT #140175898795576 id=1 cnt=1 pid=0 pos=1 obj=0 op='FAST DUAL (cr=0 pr=0 pw=0 time=2 us cost=2 size=0 card=1)' WAIT #140175898795576: nam='SQL*Net message from client' ela= 384 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1629273846399149 FETCH #140175898795576:c=9,e=3,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=1388734953,tim=1629273846399258 WAIT #140175898795576: nam='SQL*Net message to client' ela= 2 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1629273846399369

 

 

注意,正常存取需要滿足3個條件

  1. 客戶端的字符集需要支持目標字符
  2. 正確設置環境變量NLS_LANG
  3. 正確設置環境變量ORA_NCHAR_LITERAL_REPLACE

在這個案例中,sqlplus是在服務器Linux上的,因此sqlplus本身沒有字符集所以依托Linux字符集為UTF8,而UTF8滿足第一個條件。

另外,NLS_LANG=AMERICAN_AMERICA.AL32UTF8和Linux的UTF8一致是正確的。

最后ORA_NCHAR_LITERAL_REPLACE=TRUE控制了Oracle存Unicode行為。

需要注意的另外一點,由於我的Linux是遠程通過SecureCRT工具連接的,所以對應CRT的會話的字符集要設置和Linux字符集一樣:

 

也就是說如果使用windows上邊的sqlplus客戶端,該客戶端用的是936也就是簡體中文字符集。

那么即使NLS_LANG和ORA_NCHAR_LITERAL_REPLACE設置正確也會有問題,因為客戶端使用936(簡體中文)送進去特殊字符"ø"的時候就已經出問題了,936不支持"ø"。

C:\Users\admin>chcp
活動代碼頁: 936

C:\Users\admin>set nls_lang
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

C:\Users\admin>set ORA_NCHAR_LITERAL_REPLACE
ORA_NCHAR_LITERAL_REPLACE=TRUE

C:\Users\admin>sqlplus sys/zkm@192.168.1.152/zkm as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Wed Aug 18 17:07:28 2021

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

SQL> delete zkm;

2 rows deleted.

SQL> insert into zkm values ('ø',N'ø');

1 row created.

SQL> commit;

Commit complete.

SQL> col name1 for a10
SQL> col name2 for a10
SQL> select * from zkm;

NAME1      NAME2
---------- ----------
?          ?

 

 

另外,plsqldev這個工具,對於N'ø'這類特殊字符存儲進去nchar或者nvarchar2字段的時候,不需要設置ORA_NCHAR_LITERAL_REPLACE也可以成功正常存取。

對plsqdev的會話開啟10046,然后執行sql可以看出區別:

查會話sid:

 

 

然后oracle使用sys登錄對該會話做10046:

17:26:10 SYS@zkm(1264)> select a.sid,a.serial#,b.pid,b.spid from v$session a ,v$process b where a.sid=&sid and b.addr=a.paddr;
Enter value for sid: 904
old   1: select a.sid,a.serial#,b.pid,b.spid from v$session a ,v$process b where a.sid=&sid and b.addr=a.paddr
new   1: select a.sid,a.serial#,b.pid,b.spid from v$session a ,v$process b where a.sid=904 and b.addr=a.paddr

       SID    SERIAL#        PID SPID
---------- ---------- ---------- ------------------------------------------------------------------------
       904      19623        566 31314

Elapsed: 00:00:00.00
17:26:18 SYS@zkm(1264)> oradebug setospid 31314
Oracle pid: 566, Unix process pid: 31314, image: oracle@zkm
17:26:26 SYS@zkm(1264)> oradebug unlimit
Statement processed.
17:26:34 SYS@zkm(1264)> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/zkm/zkm/trace/zkm_ora_31314.trc
17:27:08 SYS@zkm(1264)> oradebug event 10046 trace name context forever,level 12
Statement processed.

 

 

執行sql以及對應的trc信息:

select N'ø' from dual;

對應trc信息:

*** 2021-08-18 17:29:08.991
WAIT #140112422498592: nam='SQL*Net message from client' ela= 3971881 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278948991660
CLOSE #140112422498592:c=35,e=35,dep=0,type=3,tim=1629278948991949
PARSE #140112422437616:c=42,e=42,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629278948992074
EXEC #140112422437616:c=31,e=31,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629278948992156
WAIT #140112422437616: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278948992214
WAIT #140112422437616: nam='SQL*Net message from client' ela= 432 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278948992721
WAIT #140112422437616: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278948992806
FETCH #140112422437616:c=75,e=75,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=1388734953,tim=1629278948992867
WAIT #140112422437616: nam='SQL*Net message from client' ela= 834 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278948993770
CLOSE #140112422437616:c=0,e=5,dep=0,type=3,tim=1629278948993881
PARSE #140112422396376:c=0,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629278948993983
BINDS #140112422396376:
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=00 csi=00 siz=48 off=0
  kxsbbbfp=7f6e770e3dd8  bln=22  avl=02  flg=05
  value=1
 Bind#1
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=00 csi=00 siz=0 off=24
  kxsbbbfp=7f6e770e3df0  bln=22  avl=02  flg=01
  value=10000
WAIT #140112422396376: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278948994352
EXEC #140112422396376:c=374,e=352,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629278948994401

*** 2021-08-18 17:29:09.050
WAIT #140112422396376: nam='SQL*Net message from client' ela= 55803 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949050287
CLOSE #140112422396376:c=71,e=71,dep=0,type=3,tim=1629278949050553
PARSE #140112422498592:c=57,e=56,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629278949050700
BINDS #140112422498592:
 Bind#0
  oacdty=01 mxl=4000(2000) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=4000 off=0
  kxsbbbfp=7f6e770e2698  bln=4000  avl=00  flg=05
WAIT #140112422498592: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949051042
EXEC #140112422498592:c=343,e=342,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629278949051110
WAIT #140112422498592: nam='SQL*Net message from client' ela= 600 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949051801
CLOSE #140112422498592:c=19,e=19,dep=0,type=3,tim=1629278949051952
=====================
PARSING IN CURSOR #140112422489040 len=33 dep=0 uid=0 oct=3 lid=0 tim=1629278949052107 hv=102554608 ad='a8c18128' sqlid='awymr8831tqzh'
select unistr('\00F8') from dual END OF STMT
PARSE #140112422489040:c=81,e=80,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629278949052105
EXEC #140112422489040:c=24,e=24,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629278949052252
WAIT #140112422489040: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949052311
WAIT #140112422489040: nam='SQL*Net message from client' ela= 341 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949052710
WAIT #140112422489040: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949052794
FETCH #140112422489040:c=65,e=65,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=1388734953,tim=1629278949052846
STAT #140112422489040 id=1 cnt=1 pid=0 pos=1 obj=0 op='FAST DUAL  (cr=0 pr=0 pw=0 time=2 us cost=2 size=0 card=1)'
WAIT #140112422489040: nam='SQL*Net message from client' ela= 13438 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949066415
PARSE #140112420550224:c=37,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=272002086,tim=1629278949066577
WAIT #140112420550224: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949066639
WAIT #140112420550224: nam='SQL*Net message from client' ela= 8714 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949075423
CLOSE #140112422489040:c=11,e=11,dep=0,type=0,tim=1629278949075532
CLOSE #140112420550224:c=7,e=8,dep=0,type=3,tim=1629278949075599
PARSE #140112422498592:c=38,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629278949075705
BINDS #140112422498592:
 Bind#0
  oacdty=01 mxl=4000(2000) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=4000 off=0
  kxsbbbfp=7f6e770e2698  bln=4000  avl=00  flg=05
WAIT #140112422498592: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949076087
EXEC #140112422498592:c=386,e=386,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629278949076150
WAIT #140112422498592: nam='SQL*Net message from client' ela= 23076 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949099319
CLOSE #140112422498592:c=39,e=39,dep=0,type=3,tim=1629278949099542
PARSE #140112422394472:c=54,e=54,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629278949099686
BINDS #140112422394472:
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=7f6e770e3620  bln=22  avl=00  flg=05
 Bind#1
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77105000  bln=32767  avl=00  flg=05
 Bind#2
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77115000  bln=32767  avl=00  flg=05
 Bind#3
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77125000  bln=32767  avl=00  flg=05
 Bind#4
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77135000  bln=32767  avl=00  flg=05
 Bind#5
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76fc5000  bln=32767  avl=00  flg=05
 Bind#6
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76fd5000  bln=32767  avl=00  flg=05
 Bind#7
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76fe5000  bln=32767  avl=00  flg=05
 Bind#8
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76ff5000  bln=32767  avl=00  flg=05
 Bind#9
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77005000  bln=32767  avl=00  flg=05
 Bind#10
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77015000  bln=32767  avl=00  flg=05
WAIT #140112422394472: nam='SQL*Net message to client' ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629278949100916
EXEC #140112422394472:c=1176,e=1219,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629278949100977

 

insert into zkm values ('ø',N'ø');

trc對應信息:

*** 2021-08-18 17:30:47.999
WAIT #140112422498592: nam='SQL*Net message from client' ela= 52681224 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279047999859
CLOSE #140112422498592:c=38,e=37,dep=0,type=3,tim=1629279048000109
PARSE #140112422437616:c=44,e=44,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629279048000238
EXEC #140112422437616:c=33,e=33,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1388734953,tim=1629279048000327
WAIT #140112422437616: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048000392
WAIT #140112422437616: nam='SQL*Net message from client' ela= 387 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048000851
WAIT #140112422437616: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048000949
FETCH #140112422437616:c=51,e=51,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=1388734953,tim=1629279048000987
WAIT #140112422437616: nam='SQL*Net message from client' ela= 556 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048001607
CLOSE #140112422437616:c=0,e=6,dep=0,type=3,tim=1629279048001681
PARSE #140112422396376:c=0,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629279048001789
BINDS #140112422396376:
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=00 csi=00 siz=48 off=0
  kxsbbbfp=7f6e770e3dd8  bln=22  avl=02  flg=05
  value=1
 Bind#1
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=00 csi=00 siz=0 off=24
  kxsbbbfp=7f6e770e3df0  bln=22  avl=02  flg=01
  value=10000
WAIT #140112422396376: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048002186
EXEC #140112422396376:c=323,e=374,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629279048002241
WAIT #140112422396376: nam='SQL*Net message from client' ela= 64591 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048066901
CLOSE #140112422396376:c=38,e=39,dep=0,type=3,tim=1629279048067161
PARSE #140112422498592:c=64,e=63,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629279048067343
BINDS #140112422498592:
 Bind#0
  oacdty=01 mxl=4000(2000) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=4000 off=0
  kxsbbbfp=7f6e770e2698  bln=4000  avl=00  flg=05
WAIT #140112422498592: nam='SQL*Net message to client' ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048067765
EXEC #140112422498592:c=440,e=439,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629279048067887
WAIT #140112422498592: nam='SQL*Net message from client' ela= 449 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048068474
CLOSE #140112422498592:c=13,e=14,dep=0,type=3,tim=1629279048068573
=====================
PARSING IN CURSOR #140112422489040 len=45 dep=0 uid=0 oct=2 lid=0 tim=1629279048069996 hv=1995508800 ad='aa58b168' sqlid='487qtctvg2320'
insert into zkm values ('?',unistr('\00F8')) END OF STMT
PARSE #140112422489040:c=1310,e=1363,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1629279048069995
EXEC #140112422489040:c=364,e=364,p=0,cr=1,cu=2,mis=0,r=1,dep=0,og=1,plh=0,tim=1629279048070521
STAT #140112422489040 id=1 cnt=0 pid=0 pos=1 obj=0 op='LOAD TABLE CONVENTIONAL  (cr=1 pr=0 pw=0 time=294 us)'
WAIT #140112422489040: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048070653

*** 2021-08-18 17:30:48.083
WAIT #140112422489040: nam='SQL*Net message from client' ela= 13060 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048083757
CLOSE #140112422489040:c=9,e=9,dep=0,type=0,tim=1629279048083949
PARSE #140112422498592:c=46,e=45,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629279048084075
BINDS #140112422498592:
 Bind#0
  oacdty=01 mxl=4000(2000) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=4000 off=0
  kxsbbbfp=7f6e770e2698  bln=4000  avl=00  flg=05
WAIT #140112422498592: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048084343
EXEC #140112422498592:c=257,e=257,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629279048084389
WAIT #140112422498592: nam='SQL*Net message from client' ela= 18285 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048102755
CLOSE #140112422498592:c=32,e=32,dep=0,type=3,tim=1629279048102955
PARSE #140112422394472:c=44,e=45,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1629279048103082
BINDS #140112422394472:
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=7f6e770e3620  bln=22  avl=00  flg=05
 Bind#1
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77105000  bln=32767  avl=00  flg=05
 Bind#2
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77115000  bln=32767  avl=00  flg=05
 Bind#3
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77125000  bln=32767  avl=00  flg=05
 Bind#4
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77135000  bln=32767  avl=00  flg=05
 Bind#5
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76fc5000  bln=32767  avl=00  flg=05
 Bind#6
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76fd5000  bln=32767  avl=00  flg=05
 Bind#7
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76fe5000  bln=32767  avl=00  flg=05
 Bind#8
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e76ff5000  bln=32767  avl=00  flg=05
 Bind#9
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77005000  bln=32767  avl=00  flg=05
 Bind#10
  oacdty=01 mxl=32767(32512) mxlc=00 mal=00 scl=00 pre=00
  oacflg=01 fl2=1000000 frm=01 csi=852 siz=32767 off=0
  kxsbbbfp=7f6e77015000  bln=32767  avl=00  flg=05
WAIT #140112422394472: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1629279048104189
EXEC #140112422394472:c=1067,e=1126,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1629279048104261

 

至此。

 

參考文檔

Storing And Retrieving Data Into NVARCHAR2 Columns Explained With Test Case (文檔 ID 2311604.1)
Writing Buffer Data With DBMS_OUTPUT.PUT_LINE Results in an Upside Down Question Mark with Multibyte Data Stored in an NVARCHAR2 Column Type (文檔 ID 1538753.1)
The National Character Set ( NLS_NCHAR_CHARACTERSET ) in Oracle 9i, 10g , 11g and 12c (文檔 ID 276914.1)
再論Oracle字符集

http://www.orafaq.com/wiki/NVARCHAR2

http://www.orafaq.com/wiki/NCHAR


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM