mashiguang

          小馬快跑

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            20 隨筆 :: 0 文章 :: 60 評論 :: 0 Trackbacks

          公告

           Oracle & Java群: 34783065
          mashiguang0833(AT).sina.com

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          鏈接高手

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          在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

          ---------- ---- -------- ----------- ---------

          NLS_BYTE   C1   VARCHAR2           7 B
            
          NLS_LENGTH_SEMANTICS allows you to specify the length of a column datatype in terms of CHARacters rather than in terms of BYTEs. Typically this is when using an AL32UTF8 or other varying width NLS_CHARACTERSET database where one character is not always one byte. While using CHAR semantics has as such no added value in a 7/8 bit characterset it's fully supported so any application code / table setup using CHAR can also be used in a 7/8bit characterset like US7ASCII/WE8MSWIN1252.
          This parameter is a 9i (and up) feature and is not available in older releases

          翻譯過來就是:這個參數允許將列的數據單位設為字符而不是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 "<owner>"."<table>" modify "<column>" 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)
           
           可以看出,在字符集為單字節的情況下,無論取何值,漢字都是以二個字節的方式存在的.

           


          本文轉自http://www.wudeyao.com/post-69.html
          posted on 2011-01-21 12:49 mashiguang 閱讀(1416) 評論(0)  編輯  收藏 所屬分類: 數據庫相關

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 衢州市| 长武县| 永济市| 山西省| 陆良县| 青州市| 油尖旺区| 丰顺县| 特克斯县| 文登市| 类乌齐县| 彰化县| 房产| 平定县| 开原市| 嘉兴市| 罗源县| 尉氏县| 滕州市| 界首市| 武乡县| 蒲城县| 安远县| 修水县| 新疆| 广州市| 西林县| 上林县| 周宁县| 邯郸县| 晋宁县| 广安市| 化隆| 黑山县| 濮阳市| 会宁县| 安庆市| 遂宁市| 屏边| 鄂托克前旗| 石阡县|