在sql server中读取XML重复标记

时间:2015-04-23 02:59:05

标签: sql-server xml sql-server-2008 xml-parsing sqlxml

 Declare @MainXml XML = 
 '<?xml version="1.0" encoding="utf-8"?>
 <result>
 <cash number="10">
 <account amt="11.00" status="Closed"/>
 <account amt="12.00" status="Closed"/>                       
 </cash>        
 <cash number="20">
 <account amt="21.00" status="Closed"/>
 <account amt="22.00" status="Closed"/>                       
 </cash>        
 </result>'

我正在使用以下查询来阅读数据

Declare @Innerxml xml; 
SELECT @Innerxml = T.c.query('<result>{/result/cash}</result>')
FROM   @MainXml.nodes('result') T(c)

SELECT  
Result.Claim.value('(./@number)[1]','varchar(max)') as C1,
Result.Claim.value('(./@amt)[1]','varchar(max)') as C2,
Result.Claim.value('(./@status)[1]','varchar(max)') as C3   
From @Innerxml.nodes('/result/cash/account') Result(Claim)

我想读取xml并存储在DB中,如下所示。

C1   C2     C3
----------------
10   11.00  Closed
10   12.00  Closed
20   21.00  Closed
20   22.00  Closed

但我的查询在C1列中仅返回NULL 请帮帮我。提前致谢

2 个答案:

答案 0 :(得分:2)

@number<cash>的属性,但您的上下文节点是<account>。在访问属性之前,您需要将XML树上升到<cash>节点。您可以执行..以获取xpath中当前节点的父节点:

SELECT  
Result.Claim.value('(../@number)[1]','varchar(max)') as C1,
Result.Claim.value('(./@amt)[1]','varchar(max)') as C2,
Result.Claim.value('(./@status)[1]','varchar(max)') as C3   
From @Innerxml.nodes('/result/cash/account') Result(Claim)

答案 1 :(得分:2)

您不应在SQL Server中的XML查询中使用父轴。创建的查询计划将为O(n 2 )。对于XML中的每个节点,都会检查XML中的所有节点。

首先在result/cash上粉碎,然后在交叉申请中粉碎account

select C.X.value('@number', 'varchar(max)') as C1,
       A.X.value('@amt', 'varchar(max)') as C2,
       A.X.value('@status', 'varchar(max)') as C3
from @MainXml.nodes('result/cash') as C(X)
  cross apply C.X.nodes('account') as A(X)

<子> 我没有看到创建第二个XML变量的意义。直接使用@MainXML