我正在读取Sql中的xml数据。
这是我的xml:
Declare @MainXml XML =
'<?xml version="1.0" encoding="utf-8"?>
<result>
<details>
<admin>
<code>555</code>
</admin>
<claimhistory>
<claim id="1" number="100">
<account>Closed</account>
</claim>
<claim id="2" number="200">
<account>Closed</account>
</claim>
</claimhistory>
</details>
</result>'
读取这样的数据:
select
C.X.value('(admin/code)[1]', 'varchar(max)') as Code,
A.X.value('@id', 'varchar(max)') as Id,
A.X.value('@number', 'varchar(max)') as No,
A.X.value('(account)[1]', 'varchar(max)') as Status
from
@MainXml.nodes('result/details') as C(X)
cross apply
C.X.nodes('claimhistory/claim') as A(X)
这是回归:
Code Id No Status
---------------------
555 1 100 Closed
555 2 200 Closed
存储过程包含上述代码。
此处数据表变量用作存储过程的输入。它包含id和名称。
Declare @dtValue As [dbo].[DataTableDetails]
Insert Into @dtValue(Requested_Id, Name) Values(1, 'Tim');
Insert Into @dtValue(Requested_Id, Name) Values(2, 'Joe');
我想基于匹配xml的Id来输入这些名称来选择查询。
预期产出 -
Code Id No Status Name
----------------------------
555 1 100 Closed Tim
555 2 200 Closed Joe
目前 - 从xml插入选定的记录后,我正在使用更新查询但是表包含超过一百万条记录,因此它现在正在影响性能。
请建议我。
编辑:
尝试使用加入 - [在选择查询中添加以下行]
Select
C.X.value('(admin/code)[1]', 'varchar(max)') as Code,
A.X.value('@id', 'varchar(max)') as Id,
A.X.value('@number', 'varchar(max)') as No,
A.X.value('(account)[1]', 'varchar(max)') as Status,
CA.Name
from
@MainXml.nodes('result/details') as C(X)
cross apply
C.X.nodes('claimhistory/claim') as A(X)
join
@dtValue CA on CA.Requested_Id = A.X.value('@id', 'varchar(max)')
答案 0 :(得分:1)
我建议重构你从XML中选择的方式:
select
C.X.value('(../../admin/code)[1]', 'varchar(max)') as Code,
C.X.value('@id', 'varchar(max)') as Id,
C.X.value('@number', 'varchar(max)') as No,
C.X.value('(account)[1]', 'varchar(max)') as Status,
dt.Name
from
@MainXml.nodes('result/details/claimhistory/claim') as C(X)
INNER JOIN @dtValue dt
ON dt.Requested_Id = C.X.value('(@id)[1]', 'int')
您实际上想要CROSS APPLY
子节点,您希望它们是您选择的主要部分(即每claim
个元素一行) - 然后很容易根据祖父节点选择得到Code
值,然后你可以正确地INNER JOIN
你的表变量。
完整样本:
Declare @MainXml XML =
'<?xml version="1.0" encoding="utf-8"?>
<result>
<details>
<admin>
<code>555</code>
</admin>
<claimhistory>
<claim id="1" number="100">
<account>Closed</account>
</claim>
<claim id="2" number="200">
<account>Closed</account>
</claim>
</claimhistory>
</details>
</result>'
DECLARE @dtValue TABLE (Requested_Id int, Name varchar(10))
Insert Into @dtValue(Requested_Id, Name) Values(1, 'Tim'), (2, 'Joe');
select
C.X.value('(../../admin/code)[1]', 'varchar(max)') as Code,
C.X.value('@id', 'varchar(max)') as Id,
C.X.value('@number', 'varchar(max)') as No,
C.X.value('(account)[1]', 'varchar(max)') as Status,
dt.Name
from
@MainXml.nodes('result/details/claimhistory/claim') as C(X)
INNER JOIN @dtValue dt
ON dt.Requested_Id = C.X.value('(@id)[1]', 'int')