SQL 根据条件实现字符串累加

现有表数据如下:
AA  BB
1   我
2   爱
3   中
4   学
5   大
6   国
7   人
需求:书写函数,当传递的参数形式如:1,2,3,6,时
输出:我,爱,中,国
这个问题困扰了我很久,一直没能实现。主要时因为必须写成函数:
我的思路时将参数解析成('1','2','3','4'),然后用in关键字进行查询。
但是,始终无法在IN后面把解析出来的值加上去。
然而,换种思路拼凑SQL字符串,通过sp_executesql 来执行,却又无法返回值。
(ps可能是我菜,一直没能通过sp_executesql实现给变量赋值)
现经高人指点,整一通用方法,有点复杂但是百试百灵,嘿嘿:
思路:SQL中想实现上面类型的参数最好时先将参数解析成数组,再将解析出来的数组传递给函数获取值。
函数1:
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO
/*
时间:2009-6-16

编写人:lop_xiaobo

功能:切割字符串,并返回生成的数据
select SplitTextToStringArray('53dab246-f635-4a88-93e5-
c2f2a871f9a7,03a22c38-272a-44c4-88a4-75d46aaf536a')
*/
ALTER   FUNCTION [dbo].[SplitTextToStringArray]
(  
   @text varchar(8000),
   @delimiter char(1)
)
RETURNS @arrayTable TABLE(Idx bigint, [Value] nvarchar(200))
AS
BEGIN
    DECLARE @splitlen int
    SET @splitlen = 4000
    DECLARE @Idx int SET @Idx = 0
    -- 定义取子串的起始位置
    DECLARE @textsplit bigint
    SET @textsplit = 1
    WHILE( @textsplit <= DATALENGTH(@text) )
    BEGIN
        -- 由于许多字符串处理函数无法用于ntext数据类型
        -- 所以需要循环按批处理ntext字符串,一批取出
        -- 个字符放入nvarchar(4000)类型的变量中.
        DECLARE @string nvarchar(4000)
        SELECT @string = SUBSTRING(@text,@textsplit,@splitlen)
        -- 能够取出满个字符
        IF LEN(@string) = @splitlen
        BEGIN
            -- 确保取出的个字符是完整的由分隔符隔开的字符串组合
            DECLARE @lastcomma int
            SELECT @lastcomma = CHARINDEX(@delimiter,REVERSE
(@string),1)
            -- 最后一个分隔符后面的字符串不完整,应抛弃
           IF @lastcomma > 0
            BEGIN
                SELECT @string = SUBSTRING(@string,1,@splitlen -
@lastcomma)
                -- 设置下一次从@text取字符的起始位置
                SELECT @textsplit = @textsplit + @splitlen - @lastcomma
+ 1
            END
            -- 最后一个分隔符后面的字符串完整.
            ELSE
            BEGIN
                SELECT @textsplit = @textsplit + @splitlen + 1
            END
        END
        -- 取出不满个字符
        ELSE
        BEGIN
            SELECT @textsplit = @textsplit + @splitlen + 1
        END
        -- 解析@string,取出以分隔符为界限的子字符串
        DECLARE @i1 int SET @i1 = 1
       DECLARE @i2 int SET @i2 = 1
        WHILE @i1 <= LEN(@string)
        BEGIN
           SET @i2 = CHARINDEX(@delimiter,@string,@i1+1)
            IF @i2 = 0
                SET @i2 = LEN(@string) + 1
            INSERT @arrayTable (Idx, Value)
            SELECT @Idx, SUBSTRING(@string,@i1,@i2-@i1)
            SET @i1 = @i2 + 1
            SET @Idx = @Idx + 1
        END
    END
    RETURN
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
-
函数2:
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
/*
时间:2009-6-16
编写人:lop_xiaobo
功能:根据条件累加相关字段成字符串
select uf_GroupNameOfUser('53dab246-f635-4a88-93e5-c2f2a871f9a7,03a22c38-272a-44c4-88a4-75d46aaf536a')
*/
ALTER  function uf_GroupNameOfUser
(
@userlist varchar(4000)
)
returns varchar(4000)
as
begin
declare @deptlist varchar(4000),@str varchar(50)
select @deptlist= ''
  DECLARE @stringArrayT TABLE(Idx bigint, [Value] nvarchar(200))
     --解析传递的参数并放入数据
     INSERT INTO @stringArrayT(Idx, [Value])
     (
        SELECT Idx, [Value]
        FROM SplitTextToStringArray(@userlist, ',')      )
--通过游标实现字符串的累加
declare cs_userdeptlist Cursor
for
  --这里书写查询语句,得到要累加的字段
  select distinct deptid from dbo.p_dept_member where userid in
  (
   select n_id from dbo.p_user_info where c_Login_name in(select [Value]  from @stringArrayT)
  )
Open cs_userdeptlist
Fetch next From cs_userdeptlist into @str
WHILE @@FETCH_STATUS = 0
BEGIN
  select @deptlist= @str + ',' + @deptlist  --累加
   Fetch next From cs_userdeptlist into @str
end
close cs_userdeptlist
deallocate cs_userdeptlist
if len(@deptlist) > 1
  select @deptlist = substring(@deptlist,1,len(@deptlist)-1)
return @deptlist
end
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
-
函数:SplitTextToStringArray 将参数解析生成数组.
函数:uf_GroupNameOfUser 供用户调用,获取值.
-
这两个函数很方便修改,解析函数不用修改,只要修改你要查询的语句就行,也就是修改游标里的内容就可以了.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值