[英]How to read data from multiple XML files in SQL Server?
I want to obtain data from multiple XML files (stored in database) and fetch them into one result set.我想从多个 XML 文件(存储在数据库中)获取数据并将它们提取到一个结果集中。 The basic working solution, with single XML file looks similar to this one :
具有单个 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)
Obviously this won't work with SELECT that returns many rows (many XML files).显然,这不适用于返回许多行(许多 XML 文件)的 SELECT。 Sub-optimal solution could be achieved using cursor (iterating over collection -> pushing data into temporary table -> SELECT (*) FROM temporary_table) however, I believe thats not necessary and more straightforward solution can be achieved.
使用游标可以实现次优解决方案(迭代集合 -> 将数据推入临时表 -> SELECT (*) FROM temporal_table)但是,我相信这不是必需的,可以实现更直接的解决方案。
How to fetch data from multiple XML files, obtained via SELECT query, into a single result-set, without using cursor?如何在不使用游标的情况下从通过 SELECT 查询获得的多个 XML 文件中获取数据到单个结果集中?
FILE_NAME || Value 1 || Value 2 || ...
----------------------------------------------
XML_FILE_1 || Node1Value || Node2Value || ...
XML_FILE_2 || Node1Value || Node2Value || ...
I've found solution thanks to @Shnugo answer.感谢@Shnugo 的回答,我找到了解决方案。
If the type of xml-container column is different then XML MS-SQL dedicated one, then double CROSS APPLY should be performed.如果 xml-container 列的类型与 XML MS-SQL 专用列不同,则应执行双 CROSS APPLY。 Example below :
下面的例子:
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)
For sure the CURSOR
approach is not needed and would be wrong entirely...当然不需要
CURSOR
方法,而且完全是错误的......
The general approach should be something like this:一般方法应该是这样的:
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);
But there are questions open:但还有一些问题没有解决:
CONVERT
extensivly... You will need a native XML in order to use .nodes()
CONVERT
......您需要一个本机 XML 才能使用.nodes()
OUTER APPLY
instead of CROSS APPLY
.OUTER APPLY
而不是CROSS APPLY
。 For demonstration a running stand-alone mockup:为了演示正在运行的独立模型:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.