如何将SELECT的输出传递给期望表的函数?

时间:2014-02-19 22:22:36

标签: tsql

我有一个知道用逗号分割字符串的函数:

SELECT * FROM dbo.SplitStrings('15,29')

返回

Item
15
29

我还有一个知道用逗号连接字符串的函数:

DECLARE @table AS SmallStrings
INSERT INTO @table VALUES ('a'),('b'),('c')
SELECT dbo.JoinStrings(@table) Joined

返回

Joined
a,b,c

现在我想分割一个字符串,修改每个项目并将它们连接起来。我也可以这样做:

DECLARE @tmp SmallStrings
INSERT INTO @tmp SELECT dbo.DayOfMonthExprToCron2(Item) Item FROM dbo.SplitStrings('15,29')
SELECT dbo.JoinStrings(@tmp) Result

返回

Result
15,L

现在我想知道我是否可以将SELECT dbo.DayOfMonthExprToCron2(Item) Item FROM dbo.SplitStrings('15,29')的结果直接传递给dbo.JoinStrings

我尝试过但失败了 - 我的卑微尝试甚至都没有编译。

天真的人:

SELECT dbo.JoinStrings(SELECT dbo.DayOfMonthExprToCron2(Item) Item FROM dbo.SplitStrings('15,29')) Result

结果

Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'SELECT'.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ')'.

修改

另一次尝试(使用双括号):

SELECT dbo.JoinStrings((SELECT dbo.DayOfMonthExprToCron2(Item) Item FROM dbo.SplitStrings('15,29'))) Result

结果

Msg 206, Level 16, State 2, Line 1
Operand type clash: nvarchar is incompatible with SmallStrings

我意识到代码是必需的,所以这就是:

CREATE FUNCTION [dbo].[SplitStrings](@List NVARCHAR(4000))
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN 
   (  
      SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
      FROM ( 
        SELECT x = CONVERT(XML, '<i>' + REPLACE(@List, ',', '</i><i>') + '</i>').query('.')
      ) AS a 
      CROSS APPLY x.nodes('i') AS y(i)
   );

CREATE FUNCTION [dbo].[JoinStrings](@strings SmallStrings READONLY)
RETURNS NVARCHAR(4000)
AS
BEGIN
    DECLARE @res NVARCHAR(32) 
    SELECT @res = COALESCE(@res + ',', '') + Item 
    FROM @strings
    WHERE Item IS NOT NULL
    RETURN @res
END

CREATE TYPE [dbo].[SmallStrings] AS TABLE([Item] [nvarchar](5) NULL)

CREATE FUNCTION [dbo].[DayOfMonthExprToCron2](@dayOfMonthExpr NVARCHAR(32))
RETURNS NVARCHAR(32)
AS
BEGIN
    DECLARE @dayOfMonth INT = CAST(@dayOfMonthExpr AS INT)

    RETURN CASE WHEN @dayOfMonth < 29 THEN @dayOfMonthExpr ELSE 'L' END
END

1 个答案:

答案 0 :(得分:0)

我认为这是不可能的。

我讨论了表值参数(TechNet)的文档以及网络上的任何提示。

我还尝试使用一组非常简化的功能集,但无法使其正常工作。