简介:使用sql和javascript两种方式统计中英文混合字符串中字节长度的办法。
历史: 以前做前台验证的时候,使用过用javascript计算中英文混合字符串的小算法,比较简单,如下:
var tempvalue = "12一二三四五345";
//有值时验证,无值时不管
if(tempvalue==null || tempvalue.length==0 || tempvalue=="" )
{
return true;
}
var i,sum;
sum=0;
for(i=0;i<tempvalue.length;i++)
{
if ((tempvalue.charCodeAt(i)>=0) && (tempvalue.charCodeAt(i)<=255))
sum=sum+1;
else
sum=sum+2;
}
即逐个判断字符串中的unicode码值,0-255之间的为1个字节,否则为2字节。
起因:前一段遇到个问题,需要在sql中计算中英混合字符串字节数。
一样使用sql函数转码,进行判断
declare @str varchar(50) , @bytelen int , @len int , @pos int,@revalue int,@char varchar(2)
set @str='123一二三五45' --要统计的字符串
set @bytelen=0 --字节总数
set @pos=1 --字符指针
set @revalue=0 --返回值if (@str is null or ltrim(rtrim(@str))='')--待处理的字符串无效
set @revalue=0
else
begin
while (@pos<=len(@str))--从第一个字符开始遍历
begin
select @char= substring(@str,@pos,1) --取出当前字符
if unicode( @char)>255 --unicode码值大于255,字节数+2,否则+1
select @bytelen=@bytelen+2
else
select @bytelen=@bytelen+1
select @pos=@pos+1--指针后移
end
end
select @revalue=@bytelen
select @revalue
这里面临时存放字符的@char 数据类型必须设为varchar(2),长度为1的话只能存一个字节,中文转码不正确。
一开始没注意这个问题,转码老是不对,还以为是思路错误,所以转用了另一个比较麻烦的方式,将字符转为2位的二进制数据,第二位值大于0x00也就大于0时,字符为2个字节,否则就是1个字节的。也做个记录备参考:
declare @str varchar(50) , @bytelen int , @pos int ,@char varchar(2),@binary binary(2),@revalue varchar(50)
set @str='123一二三五45' --要统计的字符串
set @bytelen=0 --字节总数
set @pos=1 --字符指针
set @revalue=0 --返回值if (@str is null or ltrim(rtrim(@str))='')--待处理的字符串无效
set @revalue=''
else
begin
while (@pos<=len(@str))--从第一个字符开始遍历
begin
--select ASCII(substring(@str,@pos,1)) as asi,char(ASCII(substring(@str,@pos,1))) as char1 ,substring(@str,@pos,1) as char2,@pos as pos
select @char= substring(@str,@pos,1) --取出当前字符
-- 取出当前字符的binary值,按两个字节转化,如果字符只有一个字节,转化后的值第二位值为0x00
select @binary = convert (binary(2),@char)
--如果转化后的@binary的第二个字节值大于0,说明该字符有两个字节,当前总字节数+2,否则+1
select @bytelen = case when convert(bigint,substring(@binary,2,1))>0 then @bytelen+2 else @bytelen+1 end
select @pos=@pos+1
end
end
select @bytelen--获得结果
PS: 最近又查了一下,sql 提供一个函数 datalength()可返回字节长度, 上面过程可改为根据datalength(@char)进行判断。
灯下黑,丢人了,哈哈