SQL字符串分割成若干列

在数据库编程中,很多朋友会碰到分割字符串的需求,一般都是分割成一列多行模式,但也有时会需要分割成多列一行的模式,下面我们来看下如何实现这种需求。

 

首先创建一个辅助函数,来得到生成多列的SQL语句:

create function toArray( @str nvarchar(1000), @sym nvarchar(10) ) returns nvarchar(3000) as begin set @str=rtrim(ltrim(@str)) declare @i int set @i=charindex(@sym,@str COLLATE Chinese_PRC_CS_AS_WS) declare @sql nvarchar(1000) set @sql='select ' declare @ind int=1 while @i>=1 begin set @sql=@sql+''''+left(@str,@i-1)+''' col'+CONVERT(varchar,@ind,10)+',' set @str=substring(@str,@i+1,len(@str)-@i) set @i=charindex(@sym,@str COLLATE Chinese_PRC_CS_AS_WS) set @ind=@ind+1 end if @str<>'' set @sql=@sql+''''+@str+''' col'+CONVERT(varchar,@ind,10)+',' set @sql=LEFT(@sql,LEN(@sql)-1) return @sql end

关于这个函数,应该不难理解,这里不再啰嗦

 

有了生成多列的SQL语句,应该如何去利用它呢?我们很自然的想到了临时表,将数据插入临时表不就可以用了么!

但是,临时表有两种:本地临时表和全局临时表,本地临时表的使用是受限制的,它只对当前会话起作用,我们要使用它,只能把要操作的SQL语句一起拼接到函数生成的SQL中:

declare @sql nvarchar(3000) set @sql=dbo.toArray('11-21','-')+' into #tbarr' set @sql=@sql+' select a.* from tbn a inner join #tbarr b on a.cid=b.col1 and a.bid=b.col2' set @sql=@sql+' drop table #tbarr' exec sp_executesql @sql

但是拼接SQL语句是我们应该尽量避免的思路,除非不得以,我们不用。

 

下面我们看下如何通过常规语句实现这种功能

declare @sql nvarchar(3000) set @sql=dbo.toArray('11-21','-')+' into ##tbarr' exec sp_executesql @sql select a.* from tbn a inner join ##tbarr b on a.cid=b.col1 and a.bid=b.col2 drop table ##tbarr

这样不可避免的我们使用了全局表,这也是我们应该尽量避免的编程思路,唉没办法,总是不能十全十美:(

 

也许很多朋友不理解,这样做有什么意义呢?具体要怎样的需求才会用到这个方案?

举个例子:

商品表(product)的结构是这样的:

主键 PID

类别 CID

品牌 BID

...

现在我们要查询类别ID为11品牌ID为21的所有商品,但是我们只得到了类别ID+品牌ID的字符串,那么应该如何查处对应的商品信息呢?

看示例代码:

create table product ( pid int identity(1,1), cid int, bid int, title varchar(100), dtime datetime default getdate() ) insert into product(cid,bid,title) select 10,20,'aaa' union select 11,21,'bbb' union select 12,22,'ccc' union select 13,23,'ddd' union select 14,24,'eee' go declare @sql nvarchar(3000) set @sql=dbo.toArray('11-21','-')+' into ##tbarr' --如果系统中存在表##tbarr,则删除 if exists(select name from sysobjects where name='##tbarr'and type='u') begin waitfor delay '00:00:01'--等待1秒钟 if exists(select name from sysobjects where name='##tbarr'and type='u') drop table ##tbarr end exec sp_executesql @sql select a.* from product a inner join ##tbarr b on a.cid=b.col1 and a.bid=b.col2 drop table ##tbarr

结果如下:

 

现在这个需求还比较简单,只有2个ID,如果需要判断多个呢?字符串这样“11-21-32-23” 这样一来使用这个解决方案的优点就显而易见了。

 

作者:朱会震

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值