将XML数据转换为SQL表

时间:2016-02-09 07:19:14

标签: sql-server xml

我有以下XML数据。我需要将其转换为SQL表。

<SalesDetails>
  <Customer Name="Johny" DateofBirth="1990-01-02T00:00:00">
  <OrderInfo>
    <OrderDate>1993-02-03T00:00:00</OrderDate>
    <OrderAmount>1000</OrderAmount>
  </OrderInfo>
  </Customer>
 </SalesDetails>

任何人都可以帮我提供一个SQL查询,将上述XML文件作为输出吗?

在我最初的尝试中,我创建了两个表@TI和@ T2。然后我插入了不同的值。然后我查询它:

SELECT
(SELECT * FROM @T1 FOR XML RAW('Sales') , TYPE),
(SELECT * FROM @T2 FOR XML PATH('OrderInfo') , TYPE) 
FOR XML PATH('') , ROOT('SalesDetails')

但我需要基于SQL表和相应连接的第一种XML格式的输出。也就是说,当显示顾客的姓名时,需要显示他的相应订单信息。我不希望它采用分组格式。

1 个答案:

答案 0 :(得分:3)

很抱歉,在我的第一次尝试中,我完全误读了您的问题,并认为您希望从XML中获取数据。这是从表的数据中创建这样的XML的方法:

DECLARE @cust TABLE(ID INT, CustomerName VARCHAR(100),DateOfBirth DATE);
INSERT INTO @cust VALUES(1,'Jonny','1990-01-02T00:00:00')
                       ,(2,'Jimmy','1980-01-02T00:00:00');

DECLARE @ord TABLE(ID INT,CustomerID INT,OrderDate DATE, OrderAmount INT);
INSERT INTO @ord VALUES(1,1,'1993-02-03T00:00:00',1000)
                      ,(2,1,'1994-02-03T00:00:00',500)
                      ,(3,2,'1994-02-03T00:00:00',200);

SELECT c.CustomerName AS [@Name]
      ,c.DateOfBirth AS [@DateofBirth]
      ,(
        SELECT o.OrderDate
              ,o.OrderAmount
        FROM @ord AS o
        WHERE o.CustomerID=c.ID
        FOR XML PATH('OrderInfo'),TYPE
       )
FROM @cust AS c
FOR XML PATH('Customer'),ROOT('SalesDetails')

这是创建的XML

<SalesDetails>
  <Customer Name="Jonny" DateofBirth="1990-01-02">
    <OrderInfo>
      <OrderDate>1993-02-03</OrderDate>
      <OrderAmount>1000</OrderAmount>
    </OrderInfo>
    <OrderInfo>
      <OrderDate>1994-02-03</OrderDate>
      <OrderAmount>500</OrderAmount>
    </OrderInfo>
  </Customer>
  <Customer Name="Jimmy" DateofBirth="1980-01-02">
    <OrderInfo>
      <OrderDate>1994-02-03</OrderDate>
      <OrderAmount>200</OrderAmount>
    </OrderInfo>
  </Customer>
</SalesDetails>

仅针对您想要读取XML的情况,我将附加

您可以检索以下所有信息:

生成的Index列是可用于将其插入关系表的ID。您的XML存在的问题是,缺少有关目标表的信息。但其余的应该很容易。

顺便说一下:我声明一些更相似的节点以使关系结构可见

DECLARE @x XML=
'<SalesDetails>
  <Customer Name="Johny" DateofBirth="1990-01-02T00:00:00">
    <OrderInfo>
      <OrderDate>1993-02-03T00:00:00</OrderDate>
      <OrderAmount>1000</OrderAmount>
    </OrderInfo>
    <OrderInfo>
      <OrderDate>1994-02-03T00:00:00</OrderDate>
      <OrderAmount>500</OrderAmount>
    </OrderInfo>
  </Customer>
  <Customer Name="Jimmy" DateofBirth="1980-01-02T00:00:00">
    <OrderInfo>
      <OrderDate>1994-02-03T00:00:00</OrderDate>
      <OrderAmount>200</OrderAmount>
    </OrderInfo>
    <OrderInfo>
      <OrderDate>1993-02-03T00:00:00</OrderDate>
      <OrderAmount>100</OrderAmount>
    </OrderInfo>
  </Customer>
</SalesDetails>';

WITH CustomerNodes AS
(
     SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS CustomerIndex
           ,Customer.value('@Name','varchar(max)') AS CustomerName
           ,Customer.value('@DateofBirth','date') AS CustomerDateOfBirth
           ,One.Customer.query('.') AS CustomerNode
     FROM @x.nodes('SalesDetails/Customer') AS One(Customer)
)
SELECT cn.*
      ,ROW_NUMBER() OVER(PARTITION BY cn.CustomerIndex ORDER BY (SELECT NULL)) AS OrderIndex
      ,OrderInfo.value('OrderDate[1]','date') AS OrderDate
      ,OrderInfo.value('OrderAmount[1]','int') AS OrderAmount
 FROM CustomerNodes AS cn
 CROSS APPLY cn.CustomerNode.nodes('Customer/OrderInfo') As The(OrderInfo)

结果:

Customer                 Order
ID   Name    DateOfBirth ID  OrderDate   OrderAmount
1   Johny   1990-01-02  1   1993-02-03  1000
1   Johny   1990-01-02  2   1994-02-03  500
2   Jimmy   1980-01-02  1   1994-02-03  200
2   Jimmy   1980-01-02  2   1993-02-03  100