Oracle定義字符串類型VARCHAR2和CHAR指定長(zhǎng)度的用法如下:
成都創(chuàng)新互聯(lián)是專業(yè)的云巖網(wǎng)站建設(shè)公司,云巖接單;提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行云巖網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
varchar2(
char(
那其中的BYTE和CHAR有什么區(qū)別呢
BYTE,用字節(jié)指定:VARCHAR2(10 BYTE)。這能支持最多10字節(jié)的數(shù)據(jù),在一個(gè)多字節(jié)字符集中,這可能只是兩個(gè)字符。采用多字節(jié)字符集時(shí),字節(jié)與字符并不相同。
CHAR,用字符指定:VARCHAR2(10 CHAR)。這將支持最多10字符數(shù)據(jù),可能是多達(dá)40字節(jié)的信息。另外,VARCHAR2(4000 CHAR)理論上支持最多4000個(gè)字符的數(shù)據(jù),不過(guò)由于Oracle中字符串?dāng)?shù)據(jù)類型限制為4000字節(jié),所以可能無(wú)法得到全部4000個(gè)字符。
使用UTF8之類的多字節(jié)字符集時(shí),建議你在VARCHAR2/CHAR定義中使用CHAR修飾會(huì),也就是說(shuō),使用VARCHAR2(30 CHAR),而不是VARCHAR2(30),因?yàn)槟愕谋疽夂芸赡苁嵌x一個(gè)實(shí)際上能存儲(chǔ)30字符數(shù)據(jù)的列。還可以使用會(huì)話參數(shù)或系統(tǒng)參數(shù)NLS_LENGTH_SEMANTICS來(lái)修改默認(rèn)行為,即把默認(rèn)設(shè)置BYTE改為CHAR。不建議在系統(tǒng)級(jí)修改這個(gè)設(shè)置,而應(yīng)該使用ALTER SESSION修改會(huì)話級(jí)。還有重要的一點(diǎn),VARCHAR2中存儲(chǔ)的字節(jié)數(shù)上界是4000。不過(guò),即使你指定了VARCHAR(4000 CHAR),可能并不能在這個(gè)字段中放下4000個(gè)字符實(shí)際上,采用你選擇的字符集時(shí),如果所有字符都要用4個(gè)字節(jié)來(lái)表示,那么這個(gè)字段中就只能放下1000個(gè)字符!
下面使用一個(gè)小例子展示BYTE和CHAR之間的區(qū)別,并顯示出上界的作用。
測(cè)試環(huán)境11.2.0.4,是在多字節(jié)字符集數(shù)據(jù)庫(kù)上完成的,在此使用了字符集AL32UTF8,這個(gè)字符集支持最新版本的Unicode標(biāo)準(zhǔn),采用一種變長(zhǎng)方式對(duì)每個(gè)字符使用1~4個(gè)字節(jié)進(jìn)行編碼
zx@ORCL>col value for a30 zx@ORCL>col parameter for a30 zx@ORCL>select * from nls_database_parameters where parameter='NLS_CHARACTERSET'; PARAMETER VALUE ------------------------------ ------------------------------ NLS_CHARACTERSET AL32UTF8 zx@ORCL>show parameter nls_leng NAME TYPE VALUE ------------------------------------ --------------------------------- ------------------------------ nls_length_semantics string BYTE
創(chuàng)建測(cè)試表
zx@ORCL>create table t (a varchar2(1),b varchar2(1 char),c varchar2(4000 char)); Table created.
現(xiàn)在,這個(gè)表中插入一個(gè)UTF字符unistr('\00d6'),這個(gè)字符長(zhǎng)度為2個(gè)字節(jié),可以觀察到以下結(jié)果:
zx@ORCL>select length(unistr('\00d6')),lengthb(unistr('\00d6')) from dual; LENGTH(UNISTR('\00D6')) LENGTHB(UNISTR('\00D6')) ----------------------- ------------------------ 1 2 zx@ORCL>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)
這說(shuō)明:VARCHAR(1)的單位是字節(jié)而不是字符。這里確實(shí)只有一個(gè)Unicode字符,但是它在一個(gè)字節(jié)中放不下;將應(yīng)用從單字節(jié)定寬字符集移植到一個(gè)多字節(jié)字符集時(shí),可能會(huì)發(fā)現(xiàn)原來(lái)在字段中能放下的文本現(xiàn)在卻無(wú)法放下。第二點(diǎn)的原因是:在一個(gè)單字節(jié)字符集中,包含20個(gè)字符的字符串長(zhǎng)度就是20字節(jié),完全可以在VARCHAR2(20)中放下。不過(guò)在一個(gè)多字節(jié)字符集中,20個(gè)字符的長(zhǎng)度可以達(dá)到80字節(jié)(如果每個(gè)字符用4個(gè)字節(jié)表示),這樣一杰,20個(gè)Unicode字符很可能無(wú)法在20個(gè)字節(jié)中放下。你可能會(huì)考慮將DDL修改為VARCHAR2(20 CHAR),或在運(yùn)行DDL創(chuàng)建表時(shí)使用前面提到的NLS_LENGTH_SEMENTICS會(huì)話參數(shù)。
插入包含一個(gè)字符的字段時(shí)觀察到以下結(jié)果:
zx@ORCL>insert into t (b) values (unistr('\00d6')); 1 row created. zx@ORCL>col dump for a30 zx@ORCL>select length(b),lengthb(b),dump(b) dump from t; LENGTH(B) LENGTHB(B) DUMP ---------- ---------- ------------------------------ 1 2 Typ=1 Len=2: 195,150
這個(gè)INSERT成功了,而且可以看到,所有插入數(shù)據(jù)的長(zhǎng)度(LENGTH)就是一個(gè)字符,所有字符串函數(shù)都以字符為單位工作。LENGTHB函數(shù)(字節(jié)長(zhǎng)度)顯示出這個(gè)字段占用了2字節(jié)的存儲(chǔ)空間,另外DUMP函數(shù)顯示了這些字節(jié)到底是什么。這個(gè)例子展示了VARCHAR2(N)并不一定存儲(chǔ)N個(gè)字符,而只是存儲(chǔ)N個(gè)字節(jié)。
下面測(cè)試VARCHAR2(4000)可能存儲(chǔ)不了4000個(gè)字符
zx@ORCL>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
在此顯示出,一個(gè)4000字符的實(shí)際上長(zhǎng)度為8000字節(jié),這樣一個(gè)字符串無(wú)法永久地存儲(chǔ)在一個(gè)VARCHAR(4000 char)字段中,這個(gè)字符串能放在PL/SQL變量中,因?yàn)樵赑L/SQL中VARCHAR2最大可以達(dá)到32K。不過(guò),存儲(chǔ)在表中,VARCHAR2則被硬性限制為最多只能存放4000字節(jié)。我們可以成功地存儲(chǔ)其中2000個(gè)字符:
zx@ORCL>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. zx@ORCL> zx@ORCL>select length(c),lengthb(c) from t where c is not null; LENGTH(C) LENGTHB(C) ---------- ---------- 2000 4000
輸出可見,c占用了4000個(gè)字節(jié)的存儲(chǔ)空間。