La forma más fácil de pasar de una pequeña tabla de una sola columna a una sola cadena delimitada [cerrado]

Was planning to put the following in a stored procedure but I now feel it lends itself better to being a udf.

It takes a small table like the following:

enter image description here

And returns a string like this:

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

How do I get rid of the temp table from the following so I can convert it to a function?

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;

EDITAR

With the comments and answer this seems to be a much more compact approach:

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;

preguntado el 09 de septiembre de 13 a las 21:09

Have to looked at STUFF/FOR XML PATH to create the concatenated list? I don't see why you are using a WHILE LOOP to create this. Or any of the other methods listed in this question stackoverflow.com/questions/451415/… -

@bluefeet thanks bluefeet - I'll edit OP with code using STUFF/FOR XML PATH -

1 Respuestas

As bluefeet suggested use STUFF():

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

EDIT: Sorry, I ment to illustrate the STUFF function and it was easier to test on temp table :). Your whole udf would be:

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;

Respondido el 10 de Septiembre de 13 a las 07:09

+1 thanks for implementing Bluefeets suggesting (...even if it still contains a temp table that won't work within a function :)) - por qué

ROWNUMBER was in the original as it was used in the WHILE loop ....I've edited it out of your answer. - por qué

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.