關於Oracle乙個漢字代表幾個位元組的問題

2021-09-30 09:51:22 字數 4354 閱讀 5247

在oracle定義變數時,常有varchar2 (3 char)或者varchar2 (10 byte)的資料型別,那麼3char或者10byte到底代表幾個漢字,幾個字元呢,上次外公司一同事討論這個問題,一下沒給解釋清楚,所以下來以後整理如下:

總結:當nls_characterset=al32utf8時()

nls_length_semantics=byte時,乙個漢字代表三個位元組

nls_length_semantics=char時,乙個漢字代表乙個位元組

當nls_characterset=us7ascii時(字符集為單位元組)

nls_length_semantics=byte時,乙個漢字代表兩個位元組

nls_length_semantics=char時,乙個漢字代表兩個位元組

現象:select * from nls_database_parameters;

….      …………..

nls_characterset        al32utf8

nls_length_semantics byte

nls_nchar_characterset      al16utf16

nls_rdbms_version      10.2.0.4.0

sql> alter session set nls_length_semantics='byte';

sql> create table nls_byte(c1 varchar2(7));

sql> insert into nls_byte values('測試機');

insert into nls_byte values('測試機')

ora-12899: 列 "sys"."nls_byte"."c1" 的值太大 (實際值: 9, 最大值: 7)

sql> insert into nls_byte values('測試a');

1 row inserted

sql> select table_name,column_name,t.data_type,t.data_length,t.char_used from user_tab_columns t where table_name='nls_byte';

table_name colu data_typ data_length char_used

翻譯過來就是:這個引數允許將列的資料單位設為字元而不是byte.這個問題會在字符集設為utf8的時候出現. 此引數在9i以上版本有效.

nls_length_semantics 設定.

1.      nls_database_parameters中的值是在資料庫建立的時候確定的,一般都為byte

2.     此引數可以以 「alter system set nls_length_semantics=char scope=both」方式修改,但是需要重啟資料庫才能生效.

3.     也可用」 alter session set nls_length_semantics=char」使對當前session生效.

4.     此引數可以在10g以上版本中,在環境變數或登錄檔中設定(注意需要大寫),設定後從當前客戶端啟動的所有會話都採用新的取值.

5.     修改後只對新建的列生效,對於已有的列沒有作用

6.     新建或公升級db時用byte,否則xdb或dba_tables會出現問題.

7.     nls_length_semantics對sys使用者下的物件無效.

8.     如果對於7/8bit的字符集,設為byte/char意義不大,因為無論是char和byte都對應乙個byte.

測試:一.在當前session中修改此引數

sql> alter session set nls_length_semantics='char';

session altered

sql> create table nls_char(c1 varchar2(7),c2 varchar2(7));

table created

sql> desc nls_char

name type        nullable default comments

c1   varchar2(7) y                      

c2   varchar2(7) y                      

sql> insert into nls_char values('測試機','測試測試測試');

1 row inserted 

如果對於alter system,效果是一樣的

二.對於已經存在的表,

sql> desc nls_byte

name type             nullable default comments

c1   varchar2(7 byte) y                      

sql> alter table nls_byte modify c1 varchar2(7 char);

table altered

sql> desc nls_byte

name type        nullable default comments

c1   varchar2(7) y                      

sql> insert into nls_byte values('測試機');

1 row inserted

1.      exp/imp : 不能直接匯入,因為會採用source table的建表方式在target db裡建表,即使目標庫設的值為char.

*可以預先在目標庫中以char方式建表

*然後匯入,指定引數ignore=y

2. alter table

alter table ""."" modify "" char (10 char);

建立指令碼,修改列設定.

注:bug-3611750, ora-01450 online rebuild of index fails, 可以在重建索引前指定byte, 10.2.0.5以上已經修復

bug 1488174 unicode: alter system set nls_length_semantics doesn't

take effect, 用此語句修改後,實際上不起作用,需要重啟才能生效, 但是如果用alter session方式即時生效,不用重啟.

進一步測試,在另乙個字符集設為us7ascii的db設定此引數

sql> select * from nls_database_parameters

6          nls_characterset  us7ascii

sql> alter session set nls_length_semantics=byte;

session altered.

sql> create table nls_byte(c1 varchar2(7));

table created.

sql> insert into  nls_byte values('測試測試');

insert into  nls_byte values('測試測試')

error at line 1:

ora-12899: value too large for column "tea"."nls_byte"."c1" (actual: 8,

maximum: 7)

sql> desc nls_byte

name                        null?    type

c1                                   varchar2(7)

sql> alter session set nls_length_semantics=char;

session altered.

sql> create table nls_char(c1 varchar2(7));

table created.

sql> insert into  nls_char values('測試測試');

insert into  nls_char values('測試測試')

error at line 1:

ora-12899: value too large for column "tea"."nls_char"."c1" (actual: 8,

maximum: 7)

sql> desc nls_char

name                        null?    type

c1                                  varchar2(7)

可以看出,在字符集為單位元組的情況下,無論取何值,漢字都是以二個位元組的方式存在的.

本文**

oracle 乙個漢字占用幾個位元組

oracle 乙個中文漢字 占用幾個位元組,要根據oracle中字符集編碼決定 檢視oracle server端字符集 select userenv language from dual 如果顯示如下,乙個漢字占用兩個位元組simplified chinese china.zhs16gbk 如果顯示...

乙個關於oracle日誌中乙個小點的總結

下午巡檢oracle資料庫,在檢視alert log時發現乙個沒見過的東西,如下 logminer krvxpsr summary for session 2147483905 logminer startscn 0 logminer endscn 0 logminer highconsumedsc...

乙個代表年月的類YearMonth

測試 vs自帶框架 using system using microsoft.visualstudio.testtools.unittesting this is a test class for yearmonthtest and is intended to contain all yearmo...