我想从多个XML文件(存储在数据库中)中获取数据,并将其提取到一个结果集中。具有单个XML文件的基本工作解决方案看起来与此类似:
DECLARE @xml xml
SET @xml =
(SELECT TOP 1 convert(varchar(max), convert(varbinary(max), [XML_FILE]))
FROM [SOME_TABLE])
SELECT
b.value('(./SomeNode/text())[1]','nvarchar(100)')) as [Some_Text],
b.value('(./SomeOtherNode/@VAL)[1]','int')) as [Some_Val]
FROM @xml.nodes('Example/File') as a(b)
很明显,这不适用于返回许多行(许多XML文件)的SELECT。可以使用游标来实现次优解决方案(遍历集合->将数据推送到临时表中->从temporary_table中进行SELECT(*)),但是,我认为这不是必需的,并且可以实现更直接的解决方案。
如何在不使用光标的情况下,将通过SELECT查询获得的多个XML文件中的数据提取到单个结果集中?
FILE_NAME || Value 1 || Value 2 || ...
----------------------------------------------
XML_FILE_1 || Node1Value || Node2Value || ...
XML_FILE_2 || Node1Value || Node2Value || ...
答案 0 :(得分:1)
确定不需要CURSOR
方法,这完全是错误的...
一般方法应该是这样的:
SELECT
b.value('(./SomeNode/text())[1]','nvarchar(100)') as [Some_Text],
b.value('(./SomeOtherNode/@VAL)[1]','int') as [Some_Val]
FROM [SOME_TABLE]
CROSS APPLY [XML_FILE].nodes('Example/File') as a(b);
但是还有很多问题:
CONVERT
...您将需要本机XML才能使用.nodes()
OUTER APPLY
代替CROSS APPLY
。为演示运行的独立样机:
DECLARE @mockup TABLE(ID INT IDENTITY, [XML_FILE] XML);
INSERT INTO @mockup VALUES('<Example><File><SomeNode>blah</SomeNode><SomeOtherNode VAL="1"/></File></Example>')
,('<Example><File><SomeNode>blub</SomeNode><SomeOtherNode VAL="2"/></File></Example>')
SELECT
ID,
b.value('(SomeNode/text())[1]','nvarchar(100)') as [Some_Text],
b.value('(SomeOtherNode/@VAL)[1]','int') as [Some_Val]
FROM @mockup
CROSS APPLY [XML_FILE].nodes('Example/File') as a(b)
答案 1 :(得分:1)
由于@Shnugo的回答,我找到了解决方案。
如果xml-container列的类型与XML MS-SQL专用的类型不同,则应执行两次CROSS APPLY。下面的示例:
DECLARE @mockup TABLE(ID INT IDENTITY, [XML_DATA] VARBINARY(MAX));
INSERT INTO @mockup VALUES('<Example><File><SomeNode>blah</SomeNode><SomeOtherNode VAL="1"/></File></Example>')
,('<Example><File><SomeNode>blub</SomeNode><SomeOtherNode VAL="2"/></File></Example>')
SELECT
ID,
b.value('(SomeNode/text())[1]','nvarchar(100)') as [Some_Text],
b.value('(SomeOtherNode/@VAL)[1]','int') as [Some_Val]
FROM @mockup
CROSS APPLY (SELECT CAST(convert(varbinary(max), [XML_DATA]) as XML)) as RAW_XML(xml_field)
CROSS APPLY RAW_XML.xml_field.nodes('Example/File') as a(b)