具有嵌套子选择的SQL Server FOR XML

时间:2017-03-28 15:35:12

标签: sql-server xml

以下sql代码

SELECT  
 b.GivenName [Individual/Name/FirstName] ,
 b.FamilyName [Individual/Name/LastName] ,
 b.Address_Country [Individual/Address/CountryCode] ,
 b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = @dwhclientNo
FOR XML PATH('Owner'), TYPE

将生成一个xml片段

<Owner>
 <Individual>
  <Name>
   <FirstName>Bob</FirstName>
   <LastName>Smith</LastName>
  </Name>
  <Address>
    <CountryCode>US</CountryCode>
    <AddressFree>123,Utah</AddressFree>
  </Address>
 </Individual>
</Owner>

如果我扩展此查询以包含要返回的子查询,例如,使用以下内容与个人关联的所有订单:

  (SELECT
     c.OrderIdentificationNumber [Individual/OrderNumber]
  FROM
   dbo.stage_Customer_Orders c
  WHERE
    c.CustomerNo = b.masterClient
  FOR
   XML PATH(''), TYPE)

我将两次获得个别部分。如何将两者合并以返回以下内容?

<Owner>
 <Individual>
  <OrderNo>12345</OrderNo>
  <OrderNo>23456</OrderNo>
   <Name>
    <FirstName>Bob</FirstName>
    <LastName>Smith</LastName>
   </Name>
   <Address>
    <CountryCode>US</CountryCode>
    <AddressFree>123,Utah</AddressFree>
  </Address>
 </Individual>
</Owner>

2 个答案:

答案 0 :(得分:1)

您可以使用子查询和[data()]来获取没有额外嵌套的列值 - 然后像以前一样使用path

SELECT  
    (SELECT      c.OrderIdentificationNumber as [data()]
     FROM dbo.stage_Customer_Orders c
     WHERE c.CustomerNo = b.masterClient
     For XML Path('OrderNo'), type) as [Individual],
     b.GivenName [Individual/Name/FirstName] ,
     b.FamilyName [Individual/Name/LastName] ,
     b.Address_Country [Individual/Address/CountryCode] ,
     b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = @dwhclientNo
FOR XML PATH('Owner'), TYPE

答案 1 :(得分:1)

尝试这样

我为独立解决方案设置了模拟方案。下次有问题时,您可以自己尝试。这使您更容易理解您的问题并为其创建一个完全可行且可测试的解决方案。

DECLARE @stage_Clients_Merge TABLE(ID INT,FirstName VARCHAR(100),LastName VARCHAR(100),CountryCode VARCHAR(100),AdressFree VARCHAR(100));
INSERT INTO @stage_Clients_Merge VALUES
 (1,'Bob','Smith','US','123/Utah')
,(2,'Jim','Doh','US','123/Maryland');


DECLARE @orders TABLE(CustomerID INT, OrderNo INT)
INSERT INTO @orders VALUES
 (1,11111),(1,12222)
,(2,21111),(2,22222);

SELECT (SELECT OrderNo FROM @orders WHERE CustomerID=b.ID FOR XML PATH(''),TYPE) AS Individual
      ,FirstName AS [Individual/Name/FirstName]
      ,LastName AS [Individual/Name/LastName]
      ,CountryCode AS [Individual/Address/CountryCode]
      ,AdressFree AS [Individual/Address/AdressFree] 
FROM @stage_Clients_Merge AS b
FOR XML PATH('Owner');