1

I have the following XML data with me. I need to convert this to SQL table.

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

Can anyone help me with a SQL query that gives the above XML file as output?

In my initial attempt, I have created two tables @TI and @T2. I had then inserted different values into it. I had then queried it as :

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

But I need the output in the first XML format based on SQL tables and corresponding joins. That is, when the name of a customer is displayed, his corresponding order information needs to be displayed. I do not want it in a grouped format.

5
  • What is the structure of your tables? Can you provide it as well as some sample data? Commented Feb 9, 2016 at 7:23
  • <SalesDetails> <Sales CustomerName="Johny" DateofBirth="1990-01-02T00:00:00" Gender="Male" /> <OrderInfo> <OrderDate>1993-02-03T00:00:00</OrderDate> <OrderAmount>1000</OrderAmount> <ItemName>Laptop</ItemName> </OrderInfo> <OrderInfo></SalesDetails> This is the output of the query. Commented Feb 9, 2016 at 7:32
  • It is not a tables structure, but again some xml. So what about original tables @t1 and @t2 you're fetching data from? Commented Feb 9, 2016 at 7:33
  • declare @t1 (customer name,dateofbirth) and inserted values. Similarly t2 Commented Feb 9, 2016 at 7:36
  • "Similarly" is not enough. What exactly coluns @t2 has? Has @t2 table any relations with t1? Why don't provide complete information if you want someone to help you? Also notice - pasting the code in comments generally is bad idea since code almost unreadable there. Istead use edit link below your question and modify it acordingly. Commented Feb 9, 2016 at 7:41

1 Answer 1

6

Sorry, in my first attempt I completely misread your question and thought you'd like to get the data out of your XML. This is the approach to create such an XML out of table's data:

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')

And this is the created 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>

Just for the case you want to read your XML, I let this appended

You can retrieve all the information like this:

The generated Index columns are IDs you can use to insert this into relational tables. The problem with your XML is, that the information about your target tabels is missing. But the rest should be easy for you.

Btw: I declared some more similar nodes to make the relational structure visible

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)

The result:

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.