有人說數據庫字段長度/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();
即可