从小型单列表到单个分隔字符串的最简单方法

时间:2013-09-09 20:09:39

标签: sql sql-server-2012

计划将以下内容放入存储过程中,但我现在觉得它更适合成为一个udf。

需要一张如下表所示的小表:

enter image description here

并返回如下字符串:

  

a@b.c; b@c.d; c@d.e

如何摆脱以下的临时表,以便将其转换为函数?

CREATE FUNCTION dbo.udf_emailString
(
    @x  NVARCHAR(50) = NULL
)
RETURNS VARCHAR(2000)
BEGIN
SET NOCOUNT ON;


--1.get all the related email addresses connected with @x and @y
WITH allAddresses(Email)
    AS
    (
    SELECT  Email
    FROM    WH.xxx.vw_Permissions
    WHERE   IndReceiveMail = 1 AND
            X = COALESCE(@x,X)
    GROUP BY Email
    )
, allAddressesRn(Email, rn)
    AS
    (
    SELECT  Email,
            ROW_NUMBER() OVER(ORDER BY Email)
    FROM    allAddresses
    ) 
SELECT  *
INTO    #EmailList
FROM    allAddressesRn;

--2.connect all of the above together seperating with semi-colons
DECLARE @fullAddress VARCHAR(2000) ='';
DECLARE @loopControl INT  = 1; 
WHILE @loopControl <= (SELECT MAX(rn) FROM #EmailList)
    BEGIN

        SET @fullAddress = 
            @fullAddress +  
                (
                SELECT  Email + '; '
                FROM    #EmailList
                WHERE   rn = @x
                );

    SET @loopControl = @loopControl + 1;
    END;

RETURN @fullAddress;

END;

编辑

通过评论和回答,这似乎是一个更紧凑的方法:

CREATE FUNCTION dbo.udf_emailString
(
    @x  NVARCHAR(50) = NULL
)
RETURNS VARCHAR(2000)
BEGIN


DECLARE @fullAddress VARCHAR(2000) ='';

SELECT @fullAddress = 
STUFF(
        (
    select '; ' + Email as [text()]
    FROM    
            (
            SELECT  Email
            FROM    WH.xxx.vw_Permissions
            WHERE   IndReceiveMail = 1 AND
                    X = COALESCE(@x,X)
            GROUP BY Email
            ) x
        for xml path ('')
)
,1,1,'');

SET @fullAddress = @fullAddress + ';';
RETURN @fullAddress;

END;

1 个答案:

答案 0 :(得分:1)

由于蓝脚建议使用STUFF():

select @fullAddress = stuff(
        (select ';' + Email as [text()]
        from #EmailList
        for xml path (''))
        ,1,1,'')

编辑: 对不起,我的意思是说明STUFF函数,它更容易在临时表上测试:)。你的整个udf将是:

CREATE FUNCTION dbo.udf_emailString
(
  @x  NVARCHAR(50) = NULL
)
RETURNS VARCHAR(2000)
BEGIN

--1.get all the related email addresses connected with @x and @y
WITH allAddresses(Email)
AS
(
SELECT  Email
FROM    WH.xxx.vw_Permissions
WHERE   IndReceiveMail = 1 AND
        X = COALESCE(@x,X)
GROUP BY Email
)
select @fullAddress = stuff(
    (select ';' + Email as [text()]
    from allAddresses
    for xml path (''))
    ,1,1,'');

 RETURN @fullAddress;

 END;