FOR XML in SQL SERVER - sql

I have this file output from sql server:
<ProductList>
<Product>
<Product_Department>Sales</Product_Department>
<Product_Category>A</Product_Category>
<Code>AA</Code>
<Description>AAA</Description>
<Price>10</Price>
</Product>
.
.
.
<Product>
.
.
.
</Product>
</ProductList>
The sql script is:
create proc xmlcollection
as
declare #XmlOutput xml
set #XmlOutput = (select * from Product
FOR XML AUTO, ROOT('ProductList'), ELEMENTS)
select #XmlOutput
go
The desired output of xml file would be:
<ProductList>
<Product DEP="Sales" CAT="A" CODE="AA" PRICE="10"></Product>
<Product.........................................></Product>
.
.
.
</ProductList>
How can I do that from FOR XML clause? Please help.

You need to use '#' to specify attribute values when using FOR XML.
See below:
SELECT
Product_Department AS '#DEP'
,Product_Category AS '#CAT'
,Code AS '#Code'
,[Description] AS '#DESC'
,Price AS '#PRICE'
FROM Product
FOR XML PATH ('Product'), ROOT ('ProductList')
As mentioned below, alternatively you could also use 'Type':
SELECT
Product_Department AS 'DEP'
,Product_Category AS 'CAT'
,Code AS 'CODE'
,[Description] AS 'DESC'
,Price AS 'PRICE'
FROM Product
FOR XML AUTO, TYPE, ROOT('ProductList')
This will return the following XML:
<ProductList>
<Product DEP="Sales" CAT="A" CODE="AA" DESC="AAA" PRICE="10" />
<Product DEP="Marketing" CAT="B" CODE="MM" DESC="BBB" PRICE="15" />
</ProductList>
I hope that helps.

Related

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.

Add sub tag into XML_VAR using FOR XML PATH resultset

I try with a unique query to get a #xml_var with sub tag..but I've never done for a resulset of this king. Can someone give me some tip to get the right results?
Thnaks ALEN, Italy
FROM
DECLARE #xml_var XML
SET #xml_var = (
SELECT
nRiga as LineNumber,
nRiga as BuyersOrderLineReference,
skuFornitore as SuppliersProductCode,
'' as BuyersProductCode,
FR.quantita as Amount
FROM Testate FT
JOIN Righe FR
ON (FT.idOrdine = FR.idOrdine AND FR.idStato <> 'A')
--WHERE FT.idOrdine = #idOrdine
WHERE ft.idOrdine = 'XXXXXXXXXXXXXX'
Order by fr.nRiga
FOR XML PATH('OrderLine')
)
SELECT #xml_var
my result is like...
<OrderLine>
<LineNumber>1</LineNumber>
<BuyersOrderLineReference>1</BuyersOrderLineReference>
<SuppliersProductCode>PTN-9050</SuppliersProductCode>
<BuyersProductCode />
<Amount>2</Amount>
</OrderLine>
I need something like...
<OrderLine>
<LineNumber Preserve="true">1</LineNumber>
<OrderLineReferences>
<BuyersOrderLineReference Preserve="true">1</BuyersOrderLineReference>
</OrderLineReferences>
<Product>
<SuppliersProductCode>PTN-9050</SuppliersProductCode>
<BuyersProductCode></BuyersProductCode>
</Product>
<Quantity>
<Amount>2</Amount>
</Quantity>
</OrderLine>
The following hard coded example returns the XML you seem to need:
It should be rather easy to get the values out of your tables instead.
Things might be different, if there is 1:n-data where I assume 1:1 data...
SELECT 'true' AS [LineNumber/#Preserve]
,1 AS LineNumber
,(
--I assume this is 1:n
SELECT 'true' AS [BuyersOrderLineReference/#Preserve]
,1 AS BuyersOrderLineReference
FOR XML PATH('OrderLineReferences'),TYPE
)
,'PT-9050' AS [Product/SuppliersProductCode]
,'' AS [Product/BuyersProductCode]
,2 AS [Quantity/Amount]
FOR XML PATH('OrderLine');
The result
<OrderLine>
<LineNumber Preserve="true">1</LineNumber>
<OrderLineReferences>
<BuyersOrderLineReference Preserve="true">1</BuyersOrderLineReference>
</OrderLineReferences>
<Product>
<SuppliersProductCode>PT-9050</SuppliersProductCode>
<BuyersProductCode></BuyersProductCode>
</Product>
<Quantity>
<Amount>2</Amount>
</Quantity>
</OrderLine>

How do you read an XML file in SQL?

I am using SQL Server 2014 to query XML text using xquery. I am able to insert portions of XML text to query but I need to be able to point to a local file to read and query it and cannot figure out how to do that. Below is what I have for what I am currently doing.
declare #xmldata xml
set #xmldata = '
<Orders>
<Order OrderID="100" OrderDate="1/30/2012">
<OrderDetail ProductID="1" Quantity="3">
<Price>350</Price>
</OrderDetail>
<OrderDetail ProductID="2" Quantity="8">
<Price>500</Price>
</OrderDetail>
<OrderDetail ProductID="3" Quantity="10">
<Price>700</Price>
</OrderDetail>
</Order>
<Order OrderID="200" OrderDate="2/15/2012">
<OrderDetail ProductID="4" Quantity="5">
<Price>120</Price>
</OrderDetail>
</Order>
</Orders>'
SELECT x.c.value('(OrderDetail)[2]', 'varchar(100)') as OrderDetail
FROM #xmldata.nodes('/Orders/Order') x(c)
--XMl File Location: "C:\Users\User\X\Example.xml")
Thanks in advance!
Try this https://msdn.microsoft.com/en-CA/library/ms191184.aspx
INSERT INTO T(XmlCol)
SELECT * FROM OPENROWSET(
BULK 'c:\SampleFolder\SampleData3.txt',
SINGLE_BLOB) AS x;

Save XML with attribute to Table in SQL Server

Hi I have XML data with attribute as input for SQL, i need this to be inserted in my table.
XML Data is
<?xml version="1.0" encoding="ISO-8859-1"?>
<MESSAGEACK>
<GUID GUID="kfafb30" SUBMITDATE="2015-10-15 11:30:29" ID="1">
<ERROR SEQ="1" CODE="28681" />
</GUID>
<GUID GUID="kfafb3" SUBMITDATE="2015-10-15 11:30:29" ID="1">
<ERROR SEQ="2" CODE="286381" />
</GUID>
</MESSAGEACK>
I want this to be inserted in below Format
GUID SUBMIT DATE ID ERROR SEQ CODE
kfafb3 2015-10-15 11:30:29 1 1 28681
kfafb3 2015-10-15 11:30:29 1 1 2868
please help.
Look into XPath and xml Data Type Methods in MSDN. This is one possible way :
declare #xml As XML = '...you XML string here...'
INSERT INTO YourTable
SELECT
guid.value('#GUID', 'varchar(100)') as 'GUID'
,guid.value('#SUBMITDATE', 'datetime') as 'SUBMIT DATE'
,guid.value('#ID', 'int') as 'ID'
,guid.value('ERROR[1]/#SEQ', 'int') as 'SEQ'
,guid.value('ERROR[1]/#CODE', 'int') as 'CODE'
FROM #xml.nodes('/MESSAGEACK/GUID') as x(guid)
Result :
just paste this into an empty query window and execute. Adapt to your needs:
DECLARE #xml XML=
'<?xml version="1.0" encoding="ISO-8859-1"?>
<MESSAGEACK>
<GUID GUID="kfafb30" SUBMITDATE="2015-10-15 11:30:29" ID="1">
<ERROR SEQ="1" CODE="28681" />
</GUID>
<GUID GUID="kfafb3" SUBMITDATE="2015-10-15 11:30:29" ID="1">
<ERROR SEQ="2" CODE="286381" />
</GUID>
</MESSAGEACK>';
SELECT Msg.Node.value('#GUID','varchar(max)') AS [GUID] --The value is no GUID, if the original values are, you could use uniqueidentifier instead of varchar(max)
,Msg.Node.value('#SUBMITDATE','datetime') AS SUBMITDATE
,Msg.Node.value('#ID','int') AS ID
,Msg.Node.value('(ERROR/#SEQ)[1]','int') AS [ERROR SEQ]
,Msg.Node.value('(ERROR/#CODE)[1]','int') AS CODE
FROM #xml.nodes('/MESSAGEACK/GUID') AS Msg(Node)

SQL XML Replacing elements

Please help! Is it possible to replace elements within an xml field of an sql database with other elements. I have tried using .modify(replace value of) but I can only replace text within elements rather than nodes.
Ultimately I am trying to update an element which may or may not contain other elements, with another element (possibly of the same name) within an XML field. (I am using SQL Server 2008)
E.g:
<Root>
<Sub>
<Value1>
</Value1>
<Value2>
</Value2>
<Value3>
</Value3>
</Sub>
</Root>
Would be replaced by:
<Root>
<SubVERSION2>
<Value1>
</Value1>
<Value2>
</Value2>
<Value3>
</Value3>
</SubVERSION2>
</Root>
Any help would be very much appreciated!
You can recreate your XML:
declare #x xml = '<Root>
<Sub>
<Value1>1
</Value1>
<Value2>2
</Value2>
<Value3>3
</Value3>
</Sub>
</Root>'
select cast(('<Root>' +
cast(
(
select t.c.query('.')
from #x.nodes('Root/Sub/*') t(c)
for xml path(''), root('SubVERSION2')
) as nvarchar(max)) + '</Root>') as xml)
produces desired output:
<Root>
<SubVERSION2>
<Value1>1
</Value1>
<Value2>2
</Value2>
<Value3>3
</Value3>
</SubVERSION2>
</Root>
declare #T table(XMLCol xml)
insert into #T values ('
<Root>
<Sub>
<Value1></Value1>
<Value2></Value2>
<Value3></Value3>
</Sub>
</Root>')
update #T set
XMLCol = XMLCol.query('for $s in Root/Sub
return
<Root>
<SubVERSION2>
{ $s/* }
</SubVERSION2>
</Root>')
Result:
<Root>
<SubVERSION2>
<Value1 />
<Value2 />
<Value3 />
</SubVERSION2>
</Root>