【发布时间】:2016-08-31 00:12:04
【问题描述】:
问题:如何在多个函数之间创建序列?
我有各种创建 xml 数据的函数,每个函数都可以创建多组“Party”节点。所有功能都从同一个父节点开始。我希望输出如下所示,其中每一方,无论它来自什么函数,都具有连续的序列号。期望的输出:
<PARTIES>
<PARTY SequenceNumber="1" label="PARTY_1">
...
<PARTY SequenceNumber="2" label="PARTY_2">
...
<PARTY SequenceNumber="3" label="PARTY_3">
...
</PARTIES>
现在我正在通过一个返回 xml 的函数输出我的 xml,并且我想要排序的函数在 PARTIES 节点下分组在一起:
SELECT [dbo].[GetFunction1Xml](@Id),
[dbo].[GetFunction2Xml](@Id),
[dbo].[GetFunction3Xml](@Id)
FOR XML PATH(''), ROOT('PARTIES'), TYPE
每个函数都从不同的地方收集信息,可能如下所示:
ALTER GetFunction1XML
...
RETURNS XML (
SELECT [label] = 'PARTY_' + CONVERT(NVARCHAR,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)))
[Var1] = ....,
[Var2] = ....,
FROM [Table]
FOR XML PATH('PARTY'), TYPE)
END;
我尝试使用序列,但它不允许在用户定义的函数中使用。
CREATE SEQUENCE Party_Seq
AS INTEGER
START WITH 1
INCREMENT BY 1
MINVALUE 1
NO CYCLE;
我还在每个函数中尝试了以下操作,因为如果我要让两个参与方在同一个函数中通过 UNION ALL 连接,它就可以工作。但是每次都重新启动到 PARTY_1,因为所有各方都在不同的功能中。
SELECT [@label] = 'PARTY_' + CONVERT(NVARCHAR,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)))
因此,例如,如果我用 1 个通用函数替换 2 个函数,它看起来像这样,它会正确打印出信息;但是我有太多的功能可以做到这一点。
ALTER GetGenericFunctionXML
...
RETURNS XML (
SELECT [@seq] = ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
[@label] = 'PARTY_' + CONVERT(NVARCHAR,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)))
[Var1] = [food].[fruit],
[Var2] = [food].[meat]
FROM ( SELECT 'Apple' AS [fruit],
'Bacon' AS [meat]
FROM [Table1]
UNION ALL
SELECT 'Grape',
'Pork'
FROM [Table2]
) AS [food]
FOR XML PATH('PARTY'), TYPE)
END;
输出:
<PARTIES>
<PARTY SequenceNumber="1" label="PARTY_1">
<Var1>Apple</Var1>
<Var2>Bacon</Var2>
<PARTY SequenceNumber="2" label="PARTY_2">
<Var1>Grape</Var1>
<Var2>Pork</Var2>
<PARTY SequenceNumber="3" label="PARTY_3">
</PARTIES>
我也尝试将参数传递给函数,但由于它们是函数,因此无法输出值(我相信只有存储过程可以做到这一点。如果我错了,请纠正我。)。
【问题讨论】:
-
您应该从您的 UDF 中发布示例数据和代码。没有这些,就不清楚你在做什么。我不知道你的 ID 是如何获得 11、12 和 13 的。
-
@btberry 这些是示例值。我已将它们更改为上面的 1、2 和 3。这就是我想要实现但我无法实现的目标。
-
您使用 UDF 有什么原因吗?像您在这里拥有的标量 UDF 将始终存在性能问题,我只是看不出您正在做什么使其成为可取或需要的。将该代码放入 cte 或子查询或其他内容中。如果出于某种原因您真的必须做 UDF,或者如果它只是一个有趣的难题,请解释一下。
-
@btberry 不,没有理由。我不知道它存在性能问题。我宁愿做性能更好、效果更好的事情。所以你是说如果我把所有的东西都包在一个 cte 里会更好?
-
@btberry 我不同意... multi-statement-table-valued-functions(
AS BEGIN...END的语法)存在严重的性能问题,但是返回一个 XML 的标量函数应该没问题。最要注意的是,调用没有完全内联,因此优化器可能找不到最佳执行计划。这取决于您为 XML 提取的数据类型...
标签: sql sql-server xml sequence user-defined-functions