问题描述
TLDR:我有一个标量函数,该函数需要一个表值参数,并返回该表的XML表示形式。现在,我需要在较大的Update语句中使用此函数,该函数的表参数由内部的Select语句生成。
嗨,
我们有一个XML类型定义,例如[dbo]。[XmlTestType],看起来像这样:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Element" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Content" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="Name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
它基本上表示元素-内容映射的集合,其中每个元素(具有名称属性)包含N个元素(字符串类型)。
我们还具有“表类型”形式的“定义”:
CREATE TYPE [dbo].[TableTestType] AS TABLE
(
[Element] VARCHAR(255) NOT NULL,[Content] VARCHAR(255) NOT NULL,PRIMARY KEY CLUSTERED ( [Element],[Content] )
);
到目前为止非常简单。我们还有两个函数,可以在此数据模型的XML表示和表表示之间进行转换:
- 具有表参数类型为[dbo]。[TableTestType]的标量函数,该参数返回类型为[dbo]。[XmlTestType]的xml。我们称它为[dbo]。[ConvertTableToXml]。
- 具有xml参数类型为[dbo]。[XmlTestType]的表值函数,它返回类型为[dbo]。[TableTestType]的表。我们称它为[dbo]。[ConvertXmlToTable]。
我们有一个单独的表,该表的其中一列使用xml数据类型:
CREATE TABLE [dbo].[SomeTable]
(
[UID] INT NOT NULL IDENTITY(1,1),[XmlData] XML (DOCUMENT [dbo].[XmlTestType]) NULL
);
到目前为止,一切工作正常,但是现在我需要在Update语句中更新Table中的XmlData。 例如,修改所有行的XmlData,以包括单独表的值。 因此,我希望要做的是这样的事情:
DECLARE @newDataForSomeTable AS TABLE
(
[FK_dbo__SomeTable__UID] INT NOT NULL,[Element] VARCHAR(255) NOT NULL,[Content] VARCHAR(255) NOT NULL
);
/* @newDataForSomeTable gets filled */
UPDATE [tbl] SET [tbl].[XmlData] = [calc].[XmlData]
FROM [dbo].[SomeTable] AS [tbl]
CROSS APPLY
(
SELECT [dbo].[ConvertTableToXml](
SELECT
[currentState].[Element],[currentState].[Content]
FROM [dbo].[ConvertXmlToTable]([tbl].[XmlData]) AS [currentState]
UNION
SELECT
[newData].[Element],[newData].[Content]
FROM @newDataForSomeTable AS [newData]
WHERE [newData].[FK_dbo__SomeTable__UID] = [tbl].[UID]
) AS [XmlData]
) AS [calc]
像这样可能吗?意思是调用一个标量函数,该函数在Apply块内需要一个表值参数,该表值参数是使用内部select语句生成的?
现在,我别无选择,只能在表上进行游标,从行的当前状态生成类型为[dbo]。[TableTestType]的表变量,将缺少的条目插入该变量,然后将表转换回到XML;逐行更新每一行。
亲切的问候,弗兰克
解决方法
[我可以]在Apply块内调用标量函数,该标量函数需要一个表值参数
不。无法在SELECT中构造表值类型。您必须声明一个表类型的变量,然后将其插入。
或者,您可以嵌入xml.nodes解析逻辑,该逻辑将XML转换成表并放入调用查询的主体中。