截取字符串(substring函数实现不了预期的效果)

lurel 2006-04-18 08:49:52
本人在做一个信息发布的网页,想从数据库取出信息发布的标题,因为标题或长或短,因为显示格式的原因,我要对数据进行处理,超过30个字符的我要把它后面的截掉,这个判断长度我需要利用DataLength函数,因为中文和英文数字占位不一样,中文为2位,而英文和数字为1位,所以在截取的时候就出现了问题,substring函数认为汉字和英文数字的长度都是一样的.所以在截取的时候就会产生长度截取的不正确问题.我这个标题字段是varchar类型.

请问各位高手怎么解决?
...全文
712 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
DeadWolf 2006-04-19
  • 打赏
  • 举报
回复
convert(varchar(len),col)

这样呢

只取列 col的前len个字节
dp_555 2006-04-18
  • 打赏
  • 举报
回复
友情接分。。。
dulei115 2006-04-18
  • 打赏
  • 举报
回复
if object_id('testfunc') is not null drop function testfunc
go
create function testfunc(@Title varchar(200), @len int) returns varchar(200)
as
begin
declare @s varchar(200)
set @s = @Title
if datalength(@Title) > @len
begin
declare @i int, @n int
set @i = 0
set @n = @len
while @i < @len - 1
begin
if ascii(@s) > 127
begin
set @i = @i + 1
set @n = @n - 1
end
set @i = @i + 1
set @s = right(@s, len(@s) - 1)
end
if @i = @len or ascii(@s) < 128
set @s = left(@Title, @n)
else
set @s = left(@Title, @n - 1)
end
return(@s)
end
go
--测试
select 1 as id, dbo.testfunc('12345678', 5) as title
union select 2, dbo.testfunc('1234五六', 5)
union select 3, dbo.testfunc('1二三四五六', 5)
union select 4, dbo.testfunc('一二3四五六', 5)
union select 5, dbo.testfunc('一2三四五六', 5)
union select 6, dbo.testfunc('一二三四五六', 5)
union select 7, dbo.testfunc('一二3', 5)
union select 8, dbo.testfunc('一', 5)
/*
id title
------------
1 12345
2 1234
3 1二三
4 一二3
5 一2三
6 一二
7 一二3
8 一
*/
drop function testfunc
dulei115 2006-04-18
  • 打赏
  • 举报
回复
if object_id('testfunc') is not null drop function testfunc
go
create function testfunc(@Title varchar(200), @len int) returns varchar(200)
as
begin
declare @s varchar(200)
set @s = @Title
if datalength(@Title) > @len
begin
declare @i int, @n int
set @i = 0
set @n = @len
while @i < @len - 1
begin
if ascii(@s) > 127
begin
set @i = @i + 1
set @n = @n - 1
end
set @i = @i + 1
set @s = right(@s, len(@s) - 1)
end
if @i = @len or ascii(@s) < 128
set @s = left(@Title, @n)
else
set @s = left(@Title, @n - 1)
end
return(@s)
end
go
select 1 as id, dbo.testfunc('12345678', 5) as title
union select 2, dbo.testfunc('1234五六', 5)
union select 3, dbo.testfunc('1二三四五六', 5)
union select 4, dbo.testfunc('一二3四五六', 5)
union select 5, dbo.testfunc('一二三四五六', 5)
union select 6, dbo.testfunc('一', 5)
/*
id title
-------------
1 12345
2 1234
3 1二三
4 一二3
5 一二
6 一
*/
drop function testfunc
Yang_ 2006-04-18
  • 打赏
  • 举报
回复
注意效率问题,毕竟用函数判断效率不会好
lurel 2006-04-18
  • 打赏
  • 举报
回复
还是谢谢大家
暂时采纳Yang_(扬帆破浪) 的建议吧,本来如果是C++,编程的话,我就在程序中做判断了,可是感觉还是在数据库实现好一些,因为利用了asp.net的datagrid控件,限制比较死.
fyming 2006-04-18
  • 打赏
  • 举报
回复
不好意思,暂时回答不了楼主的问题,要亲自试一下……
fyming 2006-04-18
  • 打赏
  • 举报
回复
to 楼主:
呵呵,你原来是这想考虑的啊^_^
是不是说如果是汉字就取30个,如果是英文字符就取60个?用ASCII来判断……咳咳
lurel 2006-04-18
  • 打赏
  • 举报
回复
如果是简单的len之类sql语句我就不问了,毕竟我搞sql也有4年了
lurel 2006-04-18
  • 打赏
  • 举报
回复
to:fyming()
如果用len
你可以看看30个汉字比30个英文字符长多少?显示不就长短不齐了吗?
Dream_Lu 2006-04-18
  • 打赏
  • 举报
回复
select case 标题 when len(标题)>30 then left(标题,30) else 标题 from Table
不知道行不行,你試下
lurel 2006-04-18
  • 打赏
  • 举报
回复
能不能精确到半个汉字?我发现left和substring还是有误差
lsqkeke 2006-04-18
  • 打赏
  • 举报
回复
用len()函数 不用datalength()
fyming 2006-04-18
  • 打赏
  • 举报
回复
不明白楼主为什么不用len(),而一定要用datalength()呢?因为你的标题字段是varchar,因此substring(exressin,start,length)函数在这种情况下,start和length的单位将是字符数而不是字节数.干嘛要给自己找麻烦?
Yang_ 2006-04-18
  • 打赏
  • 举报
回复
考虑中英文可能混在一起,好像只能一个一个长度去试


lurel 2006-04-18
  • 打赏
  • 举报
回复
比较麻烦,有没有更好的方法,非得用表变量和临时表来解决吗?
Yang_ 2006-04-18
  • 打赏
  • 举报
回复
一样,倒到临时表,更新好了再显示
lurel 2006-04-18
  • 打赏
  • 举报
回复
我只是select,而不是要更新我的表
Yang_ 2006-04-18
  • 打赏
  • 举报
回复
减少循环

declare @i int
set @i =30
while @i>0 and exists (select 1 from 表 where datalength(标题)>30)
begin
update 表
set 标题=left(标题,@i)
where datalength(left(标题,@i))<=30
and datalength(标题)>30
set @i=@i-1
end
Yang_ 2006-04-18
  • 打赏
  • 举报
回复
笨点的方法

declare @i int
set @i =30
while @i>0
begin
update 表
set 标题=left(标题,@i)
where datalength(left(标题,@i))<=30
and datalength(标题)>30
set @i=@i-1
end



加载更多回复(3)

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧