如何在SQL Server2000中处理半个汉字的问题

/* written by enydraboy ,2003-07-17 /
/
发表于 CSDN /
/
转载请注明出处和保留此版权信息 */

在 csdn 的专家论坛中,看到有一位朋友问起关于“由于从其它数据库中导入的数据存在半个汉字的问题,所以希望能在查询语句中将这半个汉字处理掉,怎么处理都行。望各位高手不吝赐教!”的问题,启初有点意外,但是后来觉得从这个问题可以带出一些 SQL Server 汉字中存储和处理的方法,觉得有必要总结一下。

汉字是由两个字节存储的,每个字节的数值都 >127 。所以上面的问题的解决方案就是:把字符串按字节顺序截取,当出现第一个字节是 >127, 但是后面一个字节是 <127 的这种情况,就丢弃掉。

接下来,我们要明确些技术细节:

(1) 在 SQL Server 中有很多字符串相关的操作函数,但是直接去操作包含了汉字的字符串,会有点问题。说明如下: LEN 计算长度的时候,会把汉字和英文字符都看成长度一样的; substring 也是这样, ascii 是返回第一个字节的 ASCII 码。

Example:

select len(' 你好 a'),substring(' 你好 a',1,1),ascii(' 你 ')

结果是

----------- ---- - ----------

3 你 196

一定要把字符串要转换成 varbinary 来处理,才可以。

(2) SQL Server 中,如何把 ASCII 码组合成汉字,就是把高字节和底字节分别转成字符再拼接起来。如 char(210)+char(166) 就是姚这个汉字。

再明确了上面的技术细节后,接下来就可以解决问题了。我通过编写一个函数来解决问题。

create function fn_TruncSemiHanzi(@str varchar(4000))

returns varchar(8000)

as

begin

declare

@sTmp varchar(8000),@i int,@itmp int,@itmp2 int ,@stmp2 varchar(2)

select @sTmp=''

select @i=1

while @i<=len(@str)

begin

select @itmp=convert(int,substring(convert(varbinary,substring(@str ,@i,1)),1,1)) -- 截取一个字节

if @itmp>127

begin

-- 大于 127 检查后面一个字节

select @itmp2=convert(int,substring(convert(varbinary,substring(@str ,@i,1)),2,1))

if @itmp2>127

begin

select @stmp2=char(@itmp)+char(@itmp2) -- 是一个完整的汉字

end

else

begin

select @stmp2=char(@itmp2) -- 丢弃半个汉字

end

end

else

begin

select @sTmp2=char(@itmp)

end

select @sTmp=@sTmp+@stmp2

select @i=@i+1

end

return @stmp

end


测试如下:

DECLARE @str varchar(4000)

-- 设置参数值

-- 设置参数值

-- 带有半个汉字,是你这个汉字的前面一部分

select @str='b'+char(convert(int,substring(convert(varbinary,' 你 '),1,1)))+'a 你 '

select @str 带有半个汉字 ,dbo.fn_TruncSemiHanzi(@str) 去掉半个汉字

带有半个汉字 长度 去掉半个汉字 长度

------------------ ----------- --------------- -------------------

b 腶你 3 ba 你 3


我们还可以发现这样一个有趣的现象,由于我是截了半个汉字出来,结果你的前半个汉字的字符和后面一个英文字母 a 组合,成了一个怪怪的字符 腶 。

总结,通过这个问题的解决,大家可以了解汉字在 SQL Server2000 中存储和处理的基本方法,像如何区分一个字符串中是否包含了汉字,和分离字符串中中文和英文都可以套用本文中方法。

本文中测试的环境是 Win2000 Server( 中文 )+SQL Server 2000( 中文 ) ,英文环境下没有测试,如有问题,欢迎大家指正。

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus