在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...