Import Relational Xml Data into sql server 2012 - sql

<Order>
<AmazonOrderID>1111-222-33</AmazonOrderID>
<MerchantOrderID>111-222-33</MerchantOrderID>
<PurchaseDate>2014-08-03T18:11:11+00:00</PurchaseDate>
<LastUpdatedDate>2014-08-03T18:11:14+00:00</LastUpdatedDate>
<OrderStatus>Pending</OrderStatus>
<SalesChannel>Amazon.in</SalesChannel>
<FulfillmentData>
<FulfillmentChannel>Amazon</FulfillmentChannel>
<ShipServiceLevel>Standard</ShipServiceLevel>
<Address>
<City>bangalore</City>
<State>karnataka</State>
<PostalCode>560038</PostalCode>
<Country>IN</Country>
</Address>
</FulfillmentData>
<OrderItem>
<ASIN>B00AW9A53Q</ASIN>
<SKU>SiM13</SKU>
<ItemStatus>Unshipped</ItemStatus>
<ProductName>Chicco 500ml Body Lotion</ProductName>
<Quantity>1</Quantity>
<ItemPrice>
<Component>
<Type>Principal</Type>
<Amount currency="INR">390.0</Amount>
</Component>
</ItemPrice>
</OrderItem>
</Order>
how can i import this xml data into relational tables. i have 2 tables one is Order and another is items.i wanna insert below mentioned line in order table with as primary key.
<AmazonOrderID>111-222-333</AmazonOrderID>
<MerchantOrderID>1111-3333-444</MerchantOrderID>
<PurchaseDate>2014-08-03T18:11:11+00:00</PurchaseDate>
<LastUpdatedDate>2014-08-03T18:11:14+00:00</LastUpdatedDate>
<OrderStatus>Pending</OrderStatus>
<SalesChannel>Amazon.in</SalesChannel>
and order item in items table with amazonid as foreign key
<OrderItem>
<ASIN>B00AW9A53Q</ASIN>
<SKU>SiM13</SKU>
<ItemStatus>Unshipped</ItemStatus>
<ProductName>Chicco 500ml Body Lotion</ProductName>
<Quantity>1</Quantity>
<ItemPrice>
<Component>
<Type>Principal</Type>
<Amount currency="INR">390.0</Amount>
</Component>
</ItemPrice>
</OrderItem>
</Order>
please anyone can provide solution for this..i will be very grateful.

Assuming you have your XML in a SQL variable of type XML called #Input, you could use this for the first part of your question:
INSERT INTO dbo.Order(AmazonOrderID, MerchantOrderID,
PurchaseDate, LastUpdateDate, OrderStatus, SalesChannel)
SELECT
AmazonOrderID = #input.value('(/Order/AmazonOrderID)[1]', 'varchar(25)'),
MerchantOrderID = #input.value('(/Order/MerchantOrderID)[1]', 'varchar(25)'),
PurchaseDate = #input.value('(/Order/PurchaseDate)[1]', 'datetimeoffset'),
LastUpdatedDate = #input.value('(/Order/LastUpdatedDate)[1]', 'datetimeoffset'),
OrderStatus = #input.value('(/Order/OrderStatus)[1]', 'varchar(20)'),
SalesChannel = #input.value('(/Order/SalesChannel)[1]', 'varchar(50)')
I'm not quite clear what you want to do with the second part of your question - are there potentially multiple <OrderItem> entries? What do you want to do about the nested <ItemPrice> structure?
And what do you mean by amazonid as foreign key - what AmazonId are you referring to?

Related

XML data retrieval when tags are of same name using sql server

For the below XML:
<SheetData>
<Finance>
<value>1000</value>
<Currency>USD</Currency>
<Attribute>Sales</Attribute>
</Finance>
<Finance>
<value>5000</value>
<Currency>USD</Currency>
<Attribute>Assets</Attribute>
</Finance>
</SheetData>
How can I retrieve the content of Value tag based on the entry in Attribute using Sql server query.
If the attribute is assets, the value should be 5000.
Try it like this
DECLARE #xml XML=
N'<SheetData>
<Finance>
<value>1000</value>
<Currency>USD</Currency>
<Attribute>Sales</Attribute>
</Finance>
<Finance>
<value>5000</value>
<Currency>USD</Currency>
<Attribute>Assets</Attribute>
</Finance>
</SheetData>';
DECLARE #attr VARCHAR(100)='Assets';
SELECT #xml.value('(/SheetData/Finance[Attribute=sql:variable("#attr")]/value/text())[1]','int')
You read the XPath as follows:
Start at SheetData and navigate down to Finance. Search for the node, where the <Attribute> is like the given variable and read the value's text from there.
UPDATE
Your second example (in comment) adds one more nesting level Component:
declare #xml xml=
'<SheetData>
<Finance>
<value>1000</value>
<GeoCurr>
<Currency>USD</Currency>
</GeoCurr>
<Component>
<Attribute>Sales</Attribute>
</Component>
</Finance>
<Finance>
<value>5000</value>
<GeoCurr>
<Currency>USD</Currency>
</GeoCurr>
<Component>
<Attribute>Assets</Attribute>
</Component>
</Finance>
</SheetData>';
DECLARE #attr VARCHAR(100)='Assets';
SELECT #xml.value('(/SheetData/Finance[Component/Attribute=sql:variable("#attr")]/value/text())[1]','int')

Read XML file to datatables using c# asp.net

I want to read XML file and bulk copy to database
My xml is like :
<products>
<product>
<id>1</id>
<name>product one</name>
<subproducts>
<subproduct>
<color>Red</color>
<stock>1</stock>
</subproduct>
<subproduct>
<color>Green</color>
<stock>2</stock>
</subproduct>
</subproducts>
<images>
<image>http://qwqeq.com</image>
<image>http://asdasd.com</image>
</images>
</product>
</products>
I want to get three datatables which are for products, subproducts and images and will try to bulk insert to the database.
How can i aschieve this ?
The way you have tried must be something like below,
DataSet objDataSet = new DataSet();
objDataSet.ReadXml("FilePath.xml");
It just groups the nodes and forms tables.
You need to do something which is explained well in the below link.
http://csharp.net-informations.com/xml/how-to-read-xml.htm
Hope this helps!
You can pass the XML into a stored procedure as XML parameter and shredd it there:
DECLARE #xml XML=
N'<products>
<product>
<id>1</id>
<name>product one</name>
<subproducts>
<subproduct>
<color>Red</color>
<stock>1</stock>
</subproduct>
<subproduct>
<color>Green</color>
<stock>2</stock>
</subproduct>
</subproducts>
<images>
<image>http://qwqeq.com</image>
<image>http://asdasd.com</image>
</images>
</product>
</products>';
SELECT p.value(N'id[1]',N'int') AS productID
,p.value(N'name[1]',N'nvarchar(max)') AS productName
,sp.value(N'color[1]','nvarchar(max)') AS subproductColor
,sp.value(N'stock[1]','int') AS subproductStock
,img.value(N'image[1]',N'nvarchar(max)') AS imageURL
--INTO #tmpTbl
FROM #xml.nodes(N'/products/product') AS A(p)
OUTER APPLY p.nodes(N'subproducts/subproduct') AS B(sp)
OUTER APPLY p.nodes(N'images') AS C(img)
The result
productID productName subproductColor subproductStock imageURL
1 product one Red 1 http://qwqeq.com
1 product one Green 2 http://qwqeq.com
Use SELECT ... INTO #tmpTbl to write the result into a staging table. Then use SELECT DISTINCT ... FROM #tmpTbl to retrieve the values for your insertion into the final structure.

How to convert nested XML into corresponding tables?

I have a complex nested XML (generated from a C# entity graph), for example:
<Customers>
<Customer>
<Id>1</Id>
<Number>12345</Number>
<Addresses>
<Address>
<Id>100</Id>
<Street>my street </street>
<city>London</city>
</Address>
<Address>
<Id>101</Id>
<street>my street 2</street>
<city>Berlin</city>
</Address>
</Addresses>
<BankDetails>
<BankDetail>
<Id>222</Id>
<Iban>DE8439834934939434333</Iban>
</BankDetail>
<BankDetail>
<Id>228</Id>
<Iban>UK1237921391239123213</Iban>
</BankDetail>
</BankDetails>
<Orders>
<Order>
<OrderLine>
</OrderLine>
</Order>
</Orders>
</Customer>
</Customers>
Before saving the above XML data into the actual tables, I need to process it first. For this reason, I created corresponding table types. Each of these table types have an extra column (guid as ROWGUID) so that if I'm processing new data (not yet assigned primary key) I generate a unique key. I use this column to keep the relational integrity between different table types.
What is the SQL syntax to convert the above nested XML to their corresponding tables, keeping in mind that child records must reference the generated parent guid?
Try it like this:
DECLARE #xml XML=
N'<Customers>
<Customer>
<Id>1</Id>
<AccountNumber>12345</AccountNumber>
<Addresses>
<Address>
<Id>100</Id>
<street>my street></street>
<city>London</city>
</Address>
<Address>
<Id>101</Id>
<street>my street></street>
<city>Berlin</city>
</Address>
</Addresses>
<BankDetails>
<BankDetail>
<Id>222</Id>
<Iban>DE8439834934939434333</Iban>
</BankDetail>
<BankDetail>
<Id>228</Id>
<Iban>UK1237921391239123213</Iban>
</BankDetail>
</BankDetails>
<Orders>
<Order>
<OrderLine />
</Order>
</Orders>
</Customer>
</Customers>';
--This query will create a table #tmpInsert with all the data
SELECT cust.value('Id[1]','int') AS CustomerID
,cust.value('AccountNumber[1]','int') AS CustomerAccountNumber
,addr.value('Id[1]','int') AS AddressId
,addr.value('street[1]','nvarchar(max)') AS AddressStreet
,addr.value('city[1]','nvarchar(max)') AS AddressCity
,bank.value('Id[1]','int') AS BankId
,bank.value('Iban[1]','nvarchar(max)') AS BankIban
,ord.value('OrderLine[1]','nvarchar(max)') AS OrderLine
INTO #tmpInsert
FROM #xml.nodes('/Customers/Customer') AS A(cust)
OUTER APPLY cust.nodes('Addresses/Address') AS B(addr)
OUTER APPLY cust.nodes('BankDetails/BankDetail') AS C(bank)
OUTER APPLY cust.nodes('Orders/Order') AS D(ord);
--Here you can check the content
SELECT * FROM #tmpInsert;
--Clean-Up
GO
DROP TABLE #tmpInsert
Once you've got all your data in the table, you can use simple DISTINCT, GROUP BY, if needed ROW_NUMBER() OVER(PARTITION BY ...) to select each set separately for the proper insert.

Validating xml via xsd

I'm new to XSD, so please help. I've created some XML using "for xml path" in SQL Server Management Studio 2008. It looks like:
I've read some literature, where after creating such an xml, I'm supposed to run this:
But it doesn't work. As I know after saving this file in xml and clicking it twice, it should open xml in browser. But it doesn't. What is wrong? primary key is ReferenceCode. I've created xml using this query:
select p.ReferenceCode
,p.LastName
,p.FirstName
,p.BirthDate
,p.BirthPlace
,(
select d.Type
,d.Series
,d.Number
,d.IssueDate
,d.IssueAuthority
from #Document d
where d.ReferenceCode = p.ReferenceCode
for xml path ('Document'),root('Documents'),Type
)
,(
select a.Type
,a.Street
from #Address a
where a.ReferenceCode = p.ReferenceCode
for xml path ('Address'),root('Addresses'),Type
)
,(
select h.Number
from #Phone h
where h.ReferenceCode = p.ReferenceCode
for xml path ('Phone'),root('Phone'),Type
)
from #Person p
for xml path ('Person'),root('Root')
Thanks in advance
<Root>
<Person>
<ReferenceCode>10000007462</ReferenceCode>
<LastName>Артамонова</LastName>
<FirstName>Галина</FirstName>
<BirthDate>1961-07-19</BirthDate>
<BirthPlace>РОССИЙСКАЯ ФЕДЕРАЦИЯ, д. Криуша Староюрьевского р-на Тамбовской обл.</BirthPlace>
<Documents>
<Document>
<Type>21</Type>
<Series>4508</Series>
<Number>685129</Number>
<IssueDate>2006-08-16</IssueDate>
<IssueAuthority>ОВД р-на Чертаново-Центральное г. Москвы,</IssueAuthority>
</Document>
</Documents>
<Addresses>
<Address>
<Type>1</Type>
<Street>Днепропетровская ул</Street>
</Address>
<Address>
<Type>1</Type>
<Street>Декабристов ул</Street>
</Address>
<Address>
<Type>2</Type>
<Street>Днепропетровская ул</Street>
</Address>
<Address>
<Type>2</Type>
<Street>Декабристов ул</Street>
</Address>
</Addresses>
<Phones>
<Phone>
<Number>907-09-33 </Number>
</Phone>
<Phone>
<Number>+7(903)1780367 </Number>
</Phone>
</Phones>
</Person>
</Root>
Thanks a lot, problem was - I can't create xsd with above xml, please help me to create it. Answers were - use another version, it was created and then deleted, encoding is wrong.
I found the answer myself, I needed just headings which are usually put above the xml. That much.

How to make child as parent in xml tree

I am working on message broker. But the query I am doing is very simple and can be answered by any DB guy also .
here is the query code to read xml and getting xml output
SET OutputRoot.XMLNSC.root.row[rowCnt].product_Info = THE (SELECT THE(SELECT C.*:Codes.*:Code AS TyrePatternCd FROM T.*:Classification[] AS C
WHERE C.(XMLNSC.Attribute)Type = 'BRAND') AS product
FROM itemMaster.*:ItemMasterHeader[] AS T );
This gives xml output like
<root name="Product">
<row>
<product_Info>
<product>
<TyrePatternCd>002</TyrePatternCd>
</product>
</row>
</root>
How can I make it like
<root name="Product">
<row>
<product_Info>
<TyrePatternCd>002</TyrePatternCd>
</row>
</root>
If I remove the AS product in query it makes column tag in tree.
How can I make child as parent?
Use SELECT ITEM to omit the 'product' element, and directly assign the result.
SET OutputRoot.XMLNSC.root.row[rowCnt].product_Info = THE (SELECT ITEM THE(SELECT C.*:Codes.*:Code AS TyrePatternCd FROM T.*:Classification[] AS C
WHERE C.(XMLNSC.Attribute)Type = 'BRAND')
FROM itemMaster.*:ItemMasterHeader[] AS T );