ORACLE 中 VARCHAR2 類型的字段長度是按照 byte 來定義的 一個容易被忽略的問題

       很多新手在建數據庫或添加表、字段時,會這樣忽略一個問題:ORACLE 中 VARCHAR2類型的字段長度是按照 byte 來定義的。如果數據庫使用的字符集是 GBK,GB2312 或者其他定長字符集的話,這個問題似乎可以被忽略,因爲只要把數據庫的字段長度/2 就可以得到你要限制插入該字段的中文長度了。 但是,如果數據庫的字符集是 UTF-8 呢,杯具了吧,人家是變長的。
       有人說數據庫字段長度/3,這是一定不可取的,因爲 UTF-8 是變長表示的,平均爲 3byte表示一個字符,而並不是一定用 3byte。 其實人家 ORACLE 沒這麼笨,本來就可以用字符爲單位來定義 varchar2 的長度的,這個時候需要注意在建表時這樣寫:
Sql 代碼:
create table ABC_TABLE (A_FIELD varchar2(20 char)) 這個 varchar2(20 char)就表示了是用字符爲單位來定義了,而默認情況下的 varchar2(20)
這樣就是字節!如果你之前沒考慮到這個問題,而現在遇到了,又想更改你的字段定義的話,可以這樣
寫:
Sql 代碼:
alter table ABC_TABLE modify (A_FIELD varchar2(20 char)) 
但是如果你不確定究竟是怎麼定義的,或者,你想找出所有采用字節定義長度的字段,可以試試用這樣的方法:
Sql 代碼:
select * from user_tab_columns where CHAR_USED='B' 
這裏的 CHAR_USED 的意思是:如果是字符定義-'C',字節定義-'B'如果需要批量修改所有的以字節數定義的字符串長度,需要創建一個類似這樣的存儲過程:
Sql 代碼:
create or replace procedure pro_fix_varchar as 
cursor fieldList is 
 select T1.TABLE_NAME,T1.COLUMN_NAME,T1.DATA_LENGTH from USER_TAB_COLUMNS T1 
 left join user_tables T2 on T2.TABLE_NAME=T1.TABLE_NAME  where T2.TABLE_NAME is not null 
 and T2.TABLESPACE_NAME='MY_TABLESPACE' --請把這裏修改爲你自己的表空間名
 and CHAR_USED='B'; 
tblName varchar2(2000); 
fieldName varchar2(2000); 
dataLen varchar2(10); 
sqlStr varchar2(2000); 
cnt integer; 
BEGIN 
 dbms_output.put_line('begin'); 
 cnt:=0; 
 open fieldList; 
 loop 
 fetch fieldList into tblName,fieldName,dataLen; 
 exit when fieldList%notfound; 
 sqlStr:='alter table "'||tblName||'" modify ("'||fieldName||'" varchar2('||dataLen||' 
char))'; 
 execute immediate sqlStr; 
 commit; 
 cnt:=cnt+1; 
 end loop; 
 close fieldList; 
 dbms_output.put_line('fixed '||cnt||' field(s).'); 
end pro_fix_varchar; 
然後調用這個存儲過程:
Sql 代碼:
call pro_fix_varchar(); 
即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章