oracle中关于中文占用字节数,不同的数据库有不同的情况,有的占用两个字节、有的占用三个字节,现在测试环境的数据库中文占用三个字节,要实现由中英文组成的段落字符串,按照每行占用多少字节重新分段,具体应用是在润乾报表展现。
由于中文字符占用三个字节一个字符,英文字符及数字占用一个字节一个字符,通过字符去判定一行多少字,最后会出现全部汉字的一行跟全部数字的一行无法对其的情况,所以最终考虑用字节去判定一行占用字节数,最后段落划分以及对齐都能满足需求。
具体实例实现:
一、数据库中字段存储的原始值
二、通过函数调用实现需求
select FUN_STR_SPLIT(k.COMMENTS) as text_COMMENTS_first from table_name k;
CREATE OR REPLACE FUNCTION FUN_STR_SPLIT(pStr IN VARCHAR2)
RETURN VARCHAR2 AS
V_LENGTH NUMBER;--字符长度
V_STR VARCHAR2(4000);
V_STR_T VARCHAR2(4000);
V_STR_RET VARCHAR2(4000);
V_TEMP VARCHAR2(4000);
V_TEMP_CHAR VARCHAR2(20);
V_TEMP_CHAR_T VARCHAR2(20);
V_TEMP_CHAR_W VARCHAR2(20);
V_COUNT NUMBER;--回车
数量
V_COUNT_CH NUMBER;--中文占用字节数
V_COUNT_NUM NUMBER;--是否是汉字判断
V_COUNT_CH_NUM NUMBER;--中文标点
I NUMBER;
J NUMBER;
BEGIN
I :=1;
J :=1;
V_COUNT :=0;
--将字符串中回车 换成
--SELECT REPLACE(REPLACE(PSTR,CHR(10),'
'),' ','') INTO V_TEMP FROM DUAL;
SELECT REPLACE(PSTR,CHR(10),'
') INTO V_TEMP FROM DUAL;
--计算字符长度
SELECT LENGTH(V_TEMP) INTO V_LENGTH FROM DUAL;
--计算中文占用字节数
SELECT LENGTHB('啊') INTO V_COUNT_CH FROM DUAL;
--循环判断字符
WHILE I < V_LENGTH+1 LOOP
--获取对应位置字符
V_TEMP_CHAR:=SUBSTR(V_TEMP,I,1);
--判断是否是中文
select instr('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*();:/?,<>',upper(V_TEMP_CHAR)) into V_COUNT_CH from dual;
if j < 72 then
--如果是中文 (中文占用三个字节)
if V_COUNT_CH > 0 then
--判断当前字符的下一个是不是
V_TEMP_CHAR_T:=SUBSTR(V_TEMP,I+1,1);
if V_TEMP_CHAR_T = '
V_TEMP_CHAR:=SUBSTR(V_TEMP,I,5);
V_STR :=V_STR||V_TEMP_CHAR;
J :=1;
I :=I+5;
V_COUNT :=V_COUNT+1;
else
V_STR :=V_STR||V_TEMP_CHAR;
i :=i+1;
j :=j+1;
end if;
else
--判断当前字符的下一个是不是
V_TEMP_CHAR_T:=SUBSTR(V_TEMP,I+1,1);
if V_TEMP_CHAR_T = '
V_TEMP_CHAR:=SUBSTR(V_TEMP,I,5);
V_STR :=V_STR||V_TEMP_CHAR;
J :=1;
I :=I+5;
V_COUNT :=V_COUNT+1;
else
V_STR :=V_STR||V_TEMP_CHAR;
i :=i+1;
j :=j+3;
end if;
end if;
else
--判断当前字符的下一个是不是
V_TEMP_CHAR_T:=SUBSTR(V_TEMP,I+1,1);
--判断当前字符的下下一个是不是
V_TEMP_CHAR_W:=SUBSTR(V_TEMP,I+2,1);
if V_TEMP_CHAR_T = '
V_TEMP_CHAR:=SUBSTR(V_TEMP,I,5);
V_STR :=V_STR||V_TEMP_CHAR;
J :=1;
I :=I+5;
V_COUNT :=V_COUNT+1;
elsif V_TEMP_CHAR_T = chr(13) then
if V_TEMP_CHAR_W = '
V_TEMP_CHAR:=SUBSTR(V_TEMP,I,5);
V_STR :=V_STR||V_TEMP_CHAR;
J :=1;
I :=I+5;
V_COUNT :=V_COUNT+1;
end if;
else
--判断中文标点
select instr('。,?!.',upper(V_TEMP_CHAR_T)) into V_COUNT_CH_NUM from dual;
if V_COUNT_CH_NUM > 0 then
V_STR :=V_STR||V_TEMP_CHAR||V_TEMP_CHAR_T||'
';
J:=1;
I :=I+2;
V_COUNT :=V_COUNT+1;
else
V_STR :=V_STR||V_TEMP_CHAR||'
';
J:=1;
I :=I+1;
V_COUNT :=V_COUNT+1;
end if;
end if;
end if;
END LOOP;
RETURN(V_STR);
END FUN_STR_SPLIT;
三、通过函数转换后查询值
四、转后字段在润乾中展现效果