【附錄】 字符集(一) 漢字在oracle中佔用位元組數
一,漢字在oracle中佔用位元組數
一定要在建庫的時候就選擇好字符集,否則可能給後續的開發或者遷移帶來問題。在開發中字符集問題通常會導致應用層面上的字元越界或者亂碼問題。
先來看看2個使用不同字符集的資料庫:
先來看server1:
SQL> select * from v$nls_parameters a ;
PARAMETER VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET WE8ISO8859P1
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 RMB
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
19 rows selected
SQL> select '漢字' from dual;
'??'
------
?
再看看server2:
SQL> select * from v$nls_parameters a ;
PARAMETER VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET AL32UTF8
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 RMB
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
19 rows selected
SQL> select '漢字' from dual;
'漢字'
------
漢字
通過比較上述兩個資料庫的區別,發現他們的NLS_CHARACTERSET不同,一個是WE8ISO8859P1,而另外一個是AL32UTF8。WE8ISO8859P1是單位元組8位字符集,AL32UTF8是變長多位元組編碼。
現在的客戶端的字符集為:SIMPLIFIED CHINESE_CHINA.ZHS16GBK
WE8ISO8859P1沒有漢字編碼,一般來講,有中文字元就不應該使用這個字符集,雖然修改客戶端和伺服器端相同時可以解決亂碼問題。
有關漢字在oracle中佔用的位元組數問題:
在WE8ISO8859P1字符集下,一個漢字佔了1個位元組。
在AL32UTF8字符集下面,一個漢字佔了3個位元組。
在ZHS16GBK是佔用了2個位元組。
Varchar2,varchar,nvarchar2均為變長字元型別,char則是固定長度。
用vsize函式來看的話很明顯:
Server1:
SQL> select vsize('漢') from dual;
VSIZE('?')
-----------
1
Server2:
SQL> select vsize('漢') from dual;
VSIZE('漢')
-----------
3
而用length來看,則均為1:
Server1:
SQL> select length('漢') from dual;
LENGTH('?')
------------
1
Server2:
SQL> select length('漢') from dual;
LENGTH('漢')
------------
1
下面具體來看個對比:
Server1和server2中均建立下面的表:
create table t_test_var
(
v_char2 char(2),
v_char3 char(3),
v_varchar22 varchar2(2),
v_varchar23 varchar2(3),
v_varchar2 varchar(2),
v_varchar3 varchar(3),
v_nvarchar22 nvarchar2(2),
v_nvarchar23 nvarchar2(3)
);
然後分別在兩個資料庫中插入測試資料:
Server1:
SQL> insert into t_test_var values ('我','我','我','我','我','我','我','我');
1 row inserted
SQL> insert into t_test_var values ('我們','我們','我們','我們','我們','我們','我們','我們');
1 row inserted
SQL> insert into t_test_var values ('我們是','我們是','我們是','我們是','我們是','我們是','我們是','我們是');
insert into t_test_var values ('我們是','我們是','我們是','我們是','我們是','我們是','我們是','我們是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_CHAR2" (actual: 3, maximum: 2)
說明server1中char用一個位元組來儲存一個漢字。
修改一下最後一條插入語句,使得char型別不越界:
SQL> insert into t_test_var values ('我們','我們是','我們是','我們是','我們是','我們是','我們是','我們是');
insert into t_test_var values ('我們','我們是','我們是','我們是','我們是','我們是','我們是','我們是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_VARCHAR22" (actual: 3, maximum: 2)
SQL>
則說明了server1中的varchar2型別也是一個位元組儲存一個漢字,再次修改:
SQL> insert into t_test_var values ('我們','我們是','我們','我們是','我們是','我們是','我們是','我們是');
insert into t_test_var values ('我們','我們是','我們','我們是','我們是','我們是','我們是','我們是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_VARCHAR2" (actual: 3, maximum: 2)
則說明varchar也是一個漢字佔一個位元組儲存空間,繼續修改:
SQL> insert into t_test_var values ('我們','我們是','我們','我們是','我們','我們是','我們是','我們是');
insert into t_test_var values ('我們','我們是','我們','我們是','我們','我們是','我們是','我們是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_NVARCHAR22" (actual: 3, maximum: 2)
則說明nvarchar2也是一個漢字佔一個位元組儲存空間。
這是因為在WE8ISO8859P1字元中,根本沒有漢字編碼。所以得出以上的實驗結果。
再來看看Server2:
SQL> insert into t_test_var values ('我','我','我','我','我','我','我','我');
insert into t_test_var values ('我','我','我','我','我','我','我','我')
ORA-01401: inserted value too large for column
SQL> insert into t_test_var values ('我們','我們','我們','我們','我們','我們','我們','我們');
insert into t_test_var values ('我們','我們','我們','我們','我們','我們','我們','我們')
ORA-01401: inserted value too large for column
SQL> insert into t_test_var values ('我們是','我們是','我們是','我們是','我們是','我們是','我們是','我們是');
insert into t_test_var values ('我們是','我們是','我們是','我們是','我們是','我們是','我們是','我們是')
ORA-01401: inserted value too large for column
SQL> select cast('漢' as char(1)) from dual;
select cast('漢' as char(1)) from dual
ORA-25137: Data value out of range
SQL> select cast('漢' as char(2)) from dual;
select cast('漢' as char(2)) from dual
ORA-25137: Data value out of range
SQL> select cast('漢' as char(3)) from dual;
CAST('漢'ASCHAR(3))
-------------------
漢
SQL> insert into t_test_var (v_varchar22) values ('漢');
insert into t_test_var (v_varchar22) values ('漢')
ORA-01401: inserted value too large for column
SQL> insert into t_test_var (v_varchar23) values ('漢');
1 row inserted
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16179598/viewspace-663045/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle中文漢字佔用位元組Oracle
- JAVA——一個漢字佔用多少位元組?Java
- 獲得字串實際長度,漢字佔用2個位元組。字串
- java中基本型別佔用位元組數Java型別
- ORACLE 資料型別佔用的位元組數(轉)Oracle資料型別
- Java基本型別佔用的位元組數(char佔用幾個位元組問題)Java型別
- 用JavaScript計算字串佔用位元組數JavaScript字串
- utf-8字元所佔位元組數字元
- 驗證ORACLE不同字符集中漢字佔用的byte及NLS_LENGTH_SEMANTICS引數的影響Oracle
- 漢字-字母-位元組-位之間的轉換
- 檢視oracle 欄位的資料佔用的位元組數函式Oracle函式
- GBase 8a中一個字元佔用位元組數說明字元
- 轉_oracle的字符集_源於多位元組字符集Oracle
- Java中boolean到底佔幾位元組?JavaBoolean
- C中指標佔用的位元組數(Android之JNI)指標Android
- JAVA中求解物件所佔位元組大小Java物件
- oracle sql去掉漢字保留數字或字母OracleSQL
- oracle 一欄位 資料存在數字和漢字,只提取數字的sqlOracleSQL
- Java陣列物件佔用多少個位元組?Java陣列物件
- html 空白漢字佔位符HTML
- 1.iOS --佔用的位元組的總結iOS
- Oracle中如何判斷一個字串是否含有漢字(中文)Oracle字串
- 位元組碼技術在模組依賴分析中的應用
- 在Oracle中,如何判斷一個字串是否為數字?Oracle字串
- 雙位元組中文字符集匯出的DMP檔案匯入UTF8字符集
- 位元組跳動資料湖在實時數倉中的實踐
- 【轉】Mysql中varchar存放中文與英文所佔位元組異同MySql
- 如何獲取漢字拼音首字母?一般用於通訊錄
- 字元編碼及空白漢字佔位符字元
- 阿拉伯-漢字-數字轉換
- PHP 將數字轉換為漢字PHP
- 剖析漢字描紅在flutter中的實現原理Flutter
- 在Excel中如何獲取漢字拼音首字母?Excel
- 字串位元組數問題字串
- C#中如何按位元組數擷取字串?C#字串
- Java char 型別究竟佔幾個位元組?Java型別
- ORACLE中查詢出姓名列中 含有非漢字的字元Oracle字元
- 【ORDER BY】在ZHS16GBK字符集下Oracle漢字排序依據亦是二進位制編碼非拼音Oracle排序