我试图用T-SQL粉碎一些XML。这是我的XML(有些人可能认为它来自死锁图):
<resource-list>
<metadatalock subresource="DATA_SPACE" classid="data_space_id = 65601" dbid="7" id="lockb0553200" mode="X">
<owner-list>
<owner id="process806e5b88" mode="Sch-S" />
</owner-list>
<waiter-list>
<waiter id="process11e2cb708" mode="Sch-M" requestType="convert" />
</waiter-list>
</metadatalock>
<objectlock lockPartition="0" objid="98099390" subresource="FULL" dbid="7" objectname="" id="lockbe2cfc00" mode="Sch-M" associatedObjectId="98099390">
<owner-list>
<owner id="process11e2cb708" mode="Sch-M" />
</owner-list>
<waiter-list>
<waiter id="process806e5b88" mode="Sch-S" requestType="wait" />
</waiter-list>
</objectlock>
</resource-list>
我想要的是为每个孩子提取一个包含行的数据集(从那里我相当自信我可以使用value()函数进一步粉碎它)。换句话说,我想要这个1列,2行数据集:
<metadatalock subresource="DATA_SPACE" classid="data_space_id = 65601" dbid="7" id="lockb0553200" mode="X">
<owner-list>
<owner id="process806e5b88" mode="Sch-S" />
</owner-list>
<waiter-list>
<waiter id="process11e2cb708" mode="Sch-M" requestType="convert" />
</waiter-list>
</metadatalock>
<objectlock lockPartition="0" objid="98099390" subresource="FULL" dbid="7" objectname="" id="lockbe2cfc00" mode="Sch-M" associatedObjectId="98099390">
<owner-list>
<owner id="process11e2cb708" mode="Sch-M" />
</owner-list>
<waiter-list>
<waiter id="process806e5b88" mode="Sch-S" requestType="wait" />
</waiter-list>
</objectlock>
(我可能没有解释过这个,基本上我想要第1行中的metadatalock节点和第2行中的objectlock节点。)
这是我到目前为止所拥有的:
SELECT XEventData.XEvent.query('/')
FROM #resourceList
CROSS APPLY [resource-list].nodes('//resource-list/') AS XEventData ( XEvent )
但只返回错误:
Msg 9341,Level 16,State 1,Line 3
XQuery [#resourceList.resource-list.nodes()]:''附近的语法错误, 期待一步表达。
因此我有点卡住了。我认为我在CROSS APPLY中使用nodes()是正确的道路,但我无法得到我需要的东西。
有人可以帮忙吗?
答案 0 :(得分:1)
答案 1 :(得分:1)
感谢马丁史密斯留下评论,其中包含一个链接,引导我找到这个解决方案:
DECLARE @xml XML = '<resource-list>
<metadatalock subresource="DATA_SPACE" classid="data_space_id = 65601" dbid="7" id="lockb0553200" mode="X">
<owner-list>
<owner id="process806e5b88" mode="Sch-S" />
</owner-list>
<waiter-list>
<waiter id="process11e2cb708" mode="Sch-M" requestType="convert" />
</waiter-list>
</metadatalock>
<objectlock lockPartition="0" objid="98099390" subresource="FULL" dbid="7" objectname="" id="lockbe2cfc00" mode="Sch-M" associatedObjectId="98099390">
<owner-list>
<owner id="process11e2cb708" mode="Sch-M" />
</owner-list>
<waiter-list>
<waiter id="process806e5b88" mode="Sch-S" requestType="wait" />
</waiter-list>
</objectlock>
</resource-list>'
IF OBJECT_ID('tempdb..#resourceList') IS NOT NULL
DROP TABLE #resourceList;
SELECT [resource-list]=@xml
INTO #resourceList
SELECT MainLock.Process.query('.') AS node
FROM #resourceList
CROSS APPLY [resource-list].nodes('//resource-list') AS Lock ( List )
CROSS APPLY Lock.List.nodes('*') AS MainLock (Process)
基本上只需再次交叉申请。我也不知道.nodes('*')也非常有用。
答案 2 :(得分:0)
实际上,不需要第二个CROSS APPLY ... NODES():
SELECT Lock.List.query('.') AS node
FROM #resourceList
CROSS APPLY [resource-list].nodes('/resource-list/*') AS Lock (List)
ML