如何从SQL Server 2008返回XML,该XML由多个选择共享一个共同父级构成

Mat*_*att 5 xml sql sql-server sqlxml sql-server-2008

我已经尝试使用"FOR XML PATH","FOR XML EXPLICIT"和"FOR XML AUTO",但数据永远不会使用正确的层次结构.

基本上,我有一个父表(Customers)和3个子表.每个表都有一个customerid列.从Customers表到3个子表中的每一个都有一对多的关系.

作为一个模拟示例,我有一个父"客户"表,我有3个其他表 - 产品,爱好和车辆 - 所有与customerid相关的Customers表.

实现以下类型结构的SQL代码是什么 -

<Customers>
    <Customer customerid="1" name="Fred">
       <Products>
           <Product productname="table" />
           <Product productname="chair" />
           <Product productname="wardrobe" />
       </Products>
       <Hobbies>
           <Hobby hobbyname="Golf" />
           <Hobby hobbyname="Swimming" />
       </Hobbies>
       <Vehicles>
           <Vehicle name="Car" color="Red" />
           <Vehicle name="Bicycle" color="Blue" />
       </Vehicles>
    </Customer>
    <Customer customerid="2" name="Sue">
       <Products>
           <Product productname="CD player" />
           <Product productname="Picture frame" />
       </Products>
       <Hobbies>
           <Hobby hobbyname="Dancing" />
           <Hobby hobbyname="Reading" />
       </Hobbies>
       <Vehicles>
           <Vehicle name="Car" color="Yellow" />
       </Vehicles>
    </Customer>
</Customers>
Run Code Online (Sandbox Code Playgroud)

mar*_*c_s 5

尝试这样的事情 - 它使用FOR XML PATH和subselects为给定的客户创建"链接"子节点(我将其限制为两个子表 - 但你应该得到它的"要点",并能够将它扩展到任何链接子表的数量):

SELECT
    CustomerID AS '@CustomerID',
    CustName AS '@Name',

    (SELECT ProductName AS '@productname'
     FROM dbo.Products p
     WHERE p.CustomerID = c.CustomerID  
     FOR XML PATH('Product'), TYPE) AS 'Products',

    (SELECT HobbyName AS '@hobbyname'
     FROM dbo.Hobbies h 
     WHERE h.CUstomerID = c.CustomerID
     FOR XML PATH('Hobby'), TYPE) AS 'Hobbies'
FROM
    dbo.Customers c
FOR XML PATH('Customer'), ROOT('Customers')
Run Code Online (Sandbox Code Playgroud)

给我一个类似的输出:

<Customers>
  <Customer CustomerID="1" Name="Fred">
    <Products>
      <Product productname="Table" />
      <Product productname="Wardrobe" />
      <Product productname="Chair" />
    </Products>
    <Hobbies>
      <Hobby hobbyname="Golf" />
      <Hobby hobbyname="Swimming" />
    </Hobbies>
  </Customer>
  <Customer CustomerID="2" Name="Sue">
    <Products>
      <Product productname="CD Player" />
      <Product productname="Picture frame" />
    </Products>
    <Hobbies>
      <Hobby hobbyname="Dancing" />
      <Hobby hobbyname="Gardening" />
      <Hobby hobbyname="Reading" />
    </Hobbies>
  </Customer>
</Customers>
Run Code Online (Sandbox Code Playgroud)


Dib*_*tar 4

使用FOR XML RAW

IF OBJECT_ID ('tempdb..#customer') IS NOT NULL DROP TABLE #Customer
IF OBJECT_ID ('tempdb..#product') IS NOT NULL DROP TABLE #product
IF OBJECT_ID ('tempdb..#vehicle') IS NOT NULL DROP TABLE #Vehicle
IF OBJECT_ID ('tempdb..#hobbies') IS NOT NULL DROP TABLE #Hobbies

CREATE TABLE #Customer (id INT,name NVARCHAR(20))
INSERT INTO #customer SELECT 1,'Fred' UNION ALL SELECT 2,'Sue'

CREATE TABLE #product(customer_id INT, name NVARCHAR(20))
INSERT INTO #product
SELECt 1 AS id, 'table' as product 
UNION ALL SELECT 1 AS id, 'chair' as product 
UNION ALL SELECT 1 AS id, 'wardrobe' as product 
UNION ALL SELECT 2 AS id, 'CD Player' as product 
UNION ALL SELECT 2 AS id, 'Picture Frame' as product 


CREATE TABLE #vehicle(customer_id INT, name NVARCHAR(20),colour NVARCHAR(20))
INSERT INTO #vehicle
SELECt 1 AS id, 'Car' as vehicle,'red' as colour
UNION ALL SELECT 1 AS id, 'bicycle' as vehicle,'Blue' AS colour
UNION ALL SELECT 2 AS id, 'Car' as vehicle, 'Yellow' as colour


CREATE TABLE #hobbies(customer_id INT, name NVARCHAR(20))
INSERT INTO #hobbies
SELECt 1 AS id, 'Golf' as name
UNION ALL SELECT 1 AS id, 'Swimming' as name
UNION ALL SELECT 2 AS id, 'Dancing' as name
UNION ALL SELECT 2 AS id, 'Reading' as name

SELECT 
c.id AS id
,c.name AS name
,(SELECT p.name
    FROM #product p
    WHERE p.customer_id = c.id
    FOR XML RAW('Products'),TYPE) AS Products
,(SELECT h.name
    FROM #hobbies h
    WHERE h.customer_id = c.id
    FOR XML RAW('Hobbies'),TYPE) AS Hobbies
,(SELECT v.name,v.colour
    FROM #vehicle v
    WHERE v.customer_id = c.id
    FOR XML RAW('Vehicle'),TYPE) AS Vehicle
FROM #customer c
FOR XML RAW('Customer'), ROOT('Customers')
Run Code Online (Sandbox Code Playgroud)