如何模拟STRING_AGG(相反分割)功能

时间:2017-09-14 11:57:46

标签: sql-server sql-server-2008 tsql

如何模拟string_agg功能?

我需要得到这个

[value]
1
2
3

进入这个

1,2,3

我试过了

CREATE TYPE stringArray AS TABLE ([value] nvarchar(255))
GO

CREATE FUNCTION dbo.ufn_join 
(
    @table stringArray readonly, 
    @separator nvarchar(5) = ','
)
    RETURNS nvarchar(max)
AS
BEGIN
    RETURN stuff((select @separator + value from @table for xml path('')), 1, 1, '')
END
GO

SELECT dbo.ufn_join(
    (
    SELECT cast(1 as nvarchar(255)) as value
    UNION
    SELECT cast(2 as nvarchar(255)) as value
    UNION
    SELECT cast(3 as nvarchar(255)) as value
    )
    , DEFAULT
)

但是我收到了错误

-- Error: Operand type clash: nvarchar is incompatible with stringArray

唯一的条件是我不想使用任何类型的变量。 CLR功能也完全正常,但我有同样的问题,如何将select作为参数返回到函数

3 个答案:

答案 0 :(得分:1)

通常我想在连续行时使用此链接。有多种选择如何做到这一点,所以在这里你可以找到你最喜欢哪种方法的灵感。请注意XML PATH,因为它使用了所有CPU进程,并且可以将CPU最大化为100%。

Different concat approaches

来自链接的示例:

CREATE FUNCTION dbo.udf_select_concat ( @c INT )
RETURNS VARCHAR(MAX) AS BEGIN
DECLARE @p VARCHAR(MAX) ;
       SET @p = '' ;
    SELECT @p = @p + ProductName + ','
      FROM Northwind..Products
     WHERE CategoryId = @c ;
RETURN @p
END


SELECT CategoryId, dbo.udf_select_concat( CategoryId )
FROM Northwind..Products
GROUP BY CategoryId ;

答案 1 :(得分:1)

这是因为您声明了一个类型,将该类型设置为参数并尝试将表插入此参数(不同类型)。

试试这个:

CREATE TYPE stringArray AS TABLE ([value] nvarchar(255))
GO

CREATE FUNCTION dbo.ufn_join 
(
    @table stringArray readonly, 
    @separator nvarchar(5) = ','
)
    RETURNS nvarchar(max)
AS
BEGIN
    RETURN stuff((select @separator + value from @table for xml path('')), 1, 1, '')
END
GO

DECLARE @table stringArray

INSERT INTO @Table
SELECT cast(1 as nvarchar(255)) as value
UNION
SELECT cast(2 as nvarchar(255)) as value
UNION
SELECT cast(3 as nvarchar(255)) as value

SELECT dbo.ufn_join(
    @Table
    , DEFAULT
)

答案 2 :(得分:1)

除了TVP问题之外,通过将其转换为内联表值函数(通常称为内联标量函数(iSF)),您的函数将更加快速和高效。这篇文章详细解释了我所说的内容: How to Make Scalar UDFs Run Faster (SQL Spackle)

CREATE FUNCTION dbo.ufn_join (@separator nvarchar(5))
RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT concatinatedTxt = 
  stuff((select @separator + someTxt from dbo.someTable for xml path('')), 1, 1, '');