Oracle varchar2或char類型的byte和char的區別

來源:互聯網
上載者:User

標籤:man   --   觀察   資訊   name   idc   lin   ble   value   

Oracle定義字串類型VARCHAR2和CHAR指定長度的用法如下:

varchar2(<SIZE> <BYTE|CHAR>) <SIZE>是介於1~4000之間的一個數,表示最多佔用4000位元組的儲存空間。
char(<SIZE> <BYTE|CHAR>) <SIZE>是介於1~2000之間的一個數,表示最多佔用2000位元組的儲存空間。
那其中的BYTE和CHAR有什麼區別呢
BYTE,用位元組指定:VARCHAR2(10 BYTE)。這能支援最多10位元組的資料,在一個多位元組字元集中,這可能只是兩個字元。採用多位元組字元集時,位元組與字元並不相同。

CHAR,用字元指定:VARCHAR2(10 CHAR)。這將支援最多10字元資料,可能是多達40位元組的資訊。另外,VARCHAR2(4000 CHAR)理論上支援最多4000個字元的資料,不過由於Oracle中字串資料型別限制為4000位元組,所以可能無法得到全部4000個字元。

使用UTF8之類的多位元組字元集時,建議你在VARCHAR2/CHAR定義中使用CHAR修飾會,也就是說,使用VARCHAR2(30 CHAR),而不是VARCHAR2(30),因為你的本意很可能是定義一個實際上能儲存30字元資料的列。還可以使用會話參數或系統參數NLS_LENGTH_SEMANTICS來修改預設行為,即把預設設定BYTE改為CHAR。不建議在系統級修改這個設定,而應該使用ALTER SESSION修改會話級。還有重要的一點,VARCHAR2中儲存的位元組數上界是4000。不過,即使你指定了VARCHAR(4000 CHAR),可能並不能在這個欄位中放下4000個字元實際上,採用你選擇的字元集時,如果所有字元都要用4個位元組來表示,那麼這個欄位中就只能放下1000個字元!
下面使用一個小例子展示BYTE和CHAR之間的區別,並顯示出上界的作用。
測試環境11.2.0.4,是在多位元組字元集資料庫上完成的,在此使用了字元集AL32UTF8,這個字元集支援最新版本的Unicode標準,採用一種變長方式對每個字元使用1~4個位元組進行編碼
[email protected]>col value for a30 
[email protected]>col parameter for a30 
[email protected]>select * from nls_database_parameters where parameter=‘NLS_CHARACTERSET‘; 
  
PARAMETER              VALUE 
------------------------------ ------------------------------ 
NLS_CHARACTERSET          AL32UTF8 
[email protected]>show parameter nls_leng 
  
NAME                    TYPE                VALUE 
------------------------------------ --------------------------------- ------------------------------ 
nls_length_semantics            string                  BYTE

建立測試表

[email protected]>create table t (a varchar2(1),b varchar2(1 char),c varchar2(4000 char)); 
  
Table created.

現在,這個表中插入一個UTF字元unistr(‘\00d6‘),這個字元長度為2個位元組,可以觀察到以下結果:
[email protected]>select length(unistr(‘\00d6‘)),lengthb(unistr(‘\00d6‘)) from dual; 
  
LENGTH(UNISTR(‘\00D6‘)) LENGTHB(UNISTR(‘\00D6‘)) 
----------------------- ------------------------ 
              1            2 
  
[email protected]>insert into t (a) values (unistr(‘\00d6‘)); 
insert into t (a) values (unistr(‘\00d6‘)) 
                          * 
ERROR at line 1: 
ORA-12899: value too large for column "ZX"."T"."A" (actual: 2, maximum: 1)

這說明:VARCHAR(1)的單位是位元組而不是字元。這裡確實只有一個Unicode字元,但是它在一個位元組中放不下;將應用從單位元組定寬字元集移植到一個多位元組字元集時,可能會發現原來在欄位中能放下的文本現在卻無法放下。第二點的原因是:在一個單一位元組字元集中,包含20個字元的字串長度就是20位元組,完全可以在VARCHAR2(20)中放下。不過在一個多位元組字元集中,20個字元的長度可以達到80位元組(如果每個字元用4個位元組表示),這樣一傑,20個Unicode字元很可能無法在20個位元組中放下。你可能會考慮將DDL修改為VARCHAR2(20 CHAR),或在運行DDL建立表時使用前面提到的NLS_LENGTH_SEMENTICS會話參數。
插入包含一個字元的欄位時觀察到以下結果:
[email protected]>insert into t (b) values (unistr(‘\00d6‘)); 
  
1 row created. 
  
[email protected]>col dump for a30 
[email protected]>select length(b),lengthb(b),dump(b) dump from t; 
  
 LENGTH(B) LENGTHB(B) DUMP 
---------- ---------- ------------------------------ 
    1    2 Typ=1 Len=2: 195,150

這個INSERT成功了,而且可以看到,所有插入資料的長度(LENGTH)就是一個字元,所有字串函數都以字元為單位工作。LENGTHB函數(位元組長度)顯示出這個欄位佔用了2位元組的儲存空間,另外DUMP函數顯示了這些位元組到底是什麼。這個例子展示了VARCHAR2(N)並不一定儲存N個字元,而只是儲存N個位元組。
下面測試VARCHAR2(4000)可能儲存不了4000個字元
[email protected]>declare
  2  l_date varchar2(4000 char); 
  3  l_ch  varchar2(1 char) := unistr(‘\00d6‘); 
  4  begin
  5  l_date:=rpad(l_ch,4000,l_ch); 
  6  insert into t(c) values(l_date); 
  7  end; 
  8  / 
declare

ERROR at line 1: 
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06512: at line 6

在此顯示出,一個4000字元的實際上長度為8000位元組,這樣一個字串無法永久地儲存在一個VARCHAR(4000 char)欄位中,這個字串能放在PL/SQL變數中,因為在PL/SQL中VARCHAR2最大可以達到32K。不過,儲存在表中,VARCHAR2則被硬性限制為最多隻能存放4000位元組。我們可以成功地儲存其中2000個字元:
[email protected]>declare
  2  l_date varchar2(4000 char); 
  3  l_ch  varchar2(1 char) := unistr(‘\00d6‘); 
  4  begin
  5  l_date:=rpad(l_ch,2000,l_ch); 
  6  insert into t(c) values(l_date); 
  7  end; 
  8  / 
  
PL/SQL procedure successfully completed. 
  
[email protected]> 
[email protected]>select length(c),lengthb(c) from t where c is not null; 
  
 LENGTH(C) LENGTHB(C) 
---------- ---------- 
      2000      4000

 

 

原文地址:http://www.linuxidc.com/Linux/2017-01/139853.htm

Oracle varchar2或char類型的byte和char的區別

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.