我一直在测试 OpenXML 和 XQuery 并且 OpenXML 在执行 XQuery 方面表现出色(我相信这应该与我一直在阅读的内容相反)
我更喜欢使用 XQuery,所以我正在寻求帮助。有什么方法可以改进 Xquery?
我在一个表中有大约 10,000 个这样的 XML(并且比这个例子大得多)
<Root>
<Data Code="123" Ref="1">
<Node>
<Details Date="2021-06-28" Code="ABC" />
<Types>
<Type Type="3" Count="29" />
<Type Type="5" Count="0" />
<TypeDetails Date2="2021-06-30" />
</Type>
</Types>
<Invoice Number="1234" Version="1" />
</Node>
</Data>
</Root>
OpenXML 查询:
DECLARE name_cursor CURSOR
FOR
SELECT XML
FROM [dbo].[table]
OPEN name_cursor
DECLARE @xmlVal XML
DECLARE @idoc int
FETCH NEXT FROM name_cursor INTO @xmlVal
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC sp_xml_preparedocument @idoc OUTPUT, @xmlVal
INSERT INTO finaltable
SELECT Code, Ref, Date, Code, Number,Version, Type, Count,Date2
FROM OPENXML(@iDoc, 'Root/Data/Node/Types/Type')
WITH
(
Code [varchar](50) '../../../@Code',
Ref [varchar](50) '../../../@Ref',
Date [varchar](50) '../../Details/@Date',
Code [varchar](50) '../../Details/@Code',
Number [varchar](50) '../../Invoice/@Number',
Version [varchar](50) '../../Invoice/@Version',
Type [varchar](50) '@Type',
Count [varchar](50) '@Count',
Date2 [varchar](50) 'TypeDetails/@Date2'
)
EXEC sp_xml_removedocument @idoc
FETCH NEXT FROM name_cursor INTO @xmlVal
END
CLOSE name_cursor
DEALLOCATE name_cursor
XQuery(我还尝试了针对每个节点使用 CROSS APPLY 的不同版本):
INSERT INTO finaltable
select
c.value('(../../../@Code)[1]','nvarchar(50)') as Code
,c.value('(../../../@Ref)[1]','nvarchar(50)') as Ref
,c.value('(../../Details/@Date)[1]','nvarchar(50)') as Date
,c.value('(../../Details/@Code)[1]','nvarchar(50)') as Code
,c.value('@Type','nvarchar(50)') as Type
,c.value('@Count','nvarchar(50)') as Count
,c.value('(TypeDetails/@Date2)[1]','nvarchar(50)') as Date2
,c.value('(../../Invoice/@Number)[1]','nvarchar(50)') as Number
,c.value('(../../Invoice/@Version)[1]','nvarchar(50)') as Version
from [dbo].[table]
CROSS APPLY XML.nodes('Root/Data/Node/Types/Type') as t(c)