Before data is removed from an sql server database, it is exported and saved as an XML file in the event that this data is to be recovered at a later stage. I am now trying to get the data back into the database from an XML file but cannot find the best way to do this. The SQL server import / export wizard does not appear to support XML. I have looked at the XML Bulk Load component but this doesn't look like it would work for my issue. Has anyone any suggestions?
The XML may look like below and I woud want each row inserting:
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<prod_id>4235823</prod_id>
<productImageURL>image1.jpg</productImageURL>
<entryDate>Aug 30 2011 01:47:08:317PM</entryDate>
<category>859191</category>
<productDescription>product description 1</productDescription>
<productName>product name 1</productName>
<Price>9.99</Price>
</product>
<product>
<prod_id>8989595</prod_id>
<productImageURL>image2.jpg</productImageURL>
<entryDate>Aug 30 2011 01:47:08:317PM</entryDate>
<category>859191</category>
<productDescription>product description 2</productDescription>
<productName>product name 2</productName>
<Price>2.99</Price>
</product>
<product>
<prod_id>4575454</prod_id>
<productImageURL>image3.jpg</productImageURL>
<entryDate>Aug 30 2011 01:47:08:317PM</entryDate>
<category>859191</category>
<productDescription>product description 3</productDescription>
<productName>product name 3</productName>
<Price>5.99</Price>
</product>
</products>
SELECT
p.value('prod_id[1]','INT'),
p.value('productImageURL[1]','VARCHAR(100)'),
p.value('category[1]','VARCHAR(100)'),
p.value('productDescription[1]','VARCHAR(1000)'),
p.value('productName[1]','VARCHAR(100)'),
p.value('Price[1]','money'),
FROM #xmlfile.nodes('/Products/Product') as Product(p)
After a bit of research I found I needed the following:
DECLARE #xml xml
SET #xml = N'<Products>
<Product>
<id>4</id>
<name>Amy</name>
<age>25</age>
</Product>
<Product>
<id>7</id>
<name>Vicky</name>
<age>40</age>
</Product>
</Products>'
INSERT INTO dbo.leanne_test (id, name, age)
SELECT
doc.col.value('id[1]', 'nvarchar(10)') id
,doc.col.value('name[1]', 'varchar(100)') name
,doc.col.value('age[1]', 'nvarchar(10)') age
FROM #xml.nodes('/Products/Product') doc(col)
Related
I'm trying to create XML from SQL Server and I'm stuck with nested elements. I try different FOR XML parameters but still cannot get the correct results.
query looks like this:
SELECT
Product.ID, Product.ProductName,
(SELECT
Images.ProductImage AS image
FROM Images
WHERE Images.ProductID = Product.ID
FOR XML PATH ('image_list'), ELEMENTS, TYPE
)
FROM (SELECT DISTINCT ID, ProductName FROM Product) Product
FOR XML PATH ('products'), ELEMENTS, root ('Root')
and I want get this XML like this:
<Root>
<products>
<ID>1</ID>
<ProductName>product 1</ProductName>
<image_list>
<image>picture1.jpg</image>
<image>picture2.jpg</image>
<image>picture3.jpg</image>
</image_list>
</products>
<products>
<ID>2</ID>
<ProductName>product 2</ProductName>
<image_list>
<image>picture1.jpg</image>
<image>picture2.jpg</image>
</image_list>
</products>
</Root>
First part is OK, the image_list is a problem. Any advice?
I solved :) ..probably is good to post a qustion, after that brain starts to work :)
I add AS 'image_list' under subquery, remove ELEMENTS and PATH name.
And that's it.
SELECT
Product.ID, Product.ProductName,
(SELECT
Images.ProductImage AS image
FROM Images
WHERE Images.ProductID = Product.ID
FOR XML PATH (''), TYPE
) 'image_list'
FROM (SELECT DISTINCT ID, ProductName FROM Product) Product
FOR XML PATH ('products'), ELEMENTS, root ('Root')
Results is:
<Root>
<products>
<ID>1</ID>
<ProductName>product 1 </ProductName>
<image_list>
<image>picture1.jpg</image>
<image>picture2.jpg</image>
<image>picture3.jpg</image>
</image_list>
</products>
<products>
<ID>2</ID>
<ProductName>product 2 </ProductName>
<image_list>
<image>picture1.jpg</image>
<image>picture2.jpg</image>
</image_list>
</products>
</Root>
I am creating an SSIS package where I am pulling data from a table and need to transform it to an XML file using these columns:
select
iqr_FirstName AS FIRSTNAME,
iqr_LastName AS LASTNAME,
iqr_Employer AS EMPLOYER,
iqr_Occupation AS OCCUPATION,
iqr_Line1 AS ADR1,
iqr_City AS CITY, iqr_State AS State,
iqr_Zip AS ZIP,
iqr_CCAmount AS AMOUNT, iqr_CreatedOn AS DATE
from
std7_ImportQueueRecord
for xml path('Individual')
My issue with nesting is I need separated nodes for the following template:
<?xml version="1.0" encoding="UTF-8"?>
<DATABASE name="cc_Sample">
<INDIVIDUAL>
<LASTNAME>last</LASTNAME>
<FIRSTNAME>first</FIRSTNAME>
<MIDDLE></MIDDLE>
<NAMETITLE></NAMETITLE>
<NAMESUFFIX></NAMESUFFIX>
<BIRTHDATE></BIRTHDATE>
<OCCUPATION></OCCUPATION>
<EMPLOYER>company</EMPLOYER>
<SALUTATION>first</SALUTATION>
<GENDER></GENDER>
<ADDRESS>
<DESCR>3</DESCR>
<COMPANY></COMPANY>
<ADR1>adr1</ADR1>
<ADR2>adr2</ADR2>
<CITY>city</CITY>
<STATE>st</STATE>
<ZIP>zip</ZIP>
</ADDRESS>
<PHONENUMBER>
<USES>1</USES>
<PHONE>111-1111</PHONE>
<AREA>111</AREA>
<EXT></EXT>
</PHONENUMBER>
<PHONENUMBER>
<USES>2</USES>
<PHONE>222-2222</PHONE>
<AREA>222</AREA>
<EXT></EXT>
</PHONENUMBER>
<PHONENUMBER>
<USES>3</USES>
<PHONE>333-3333</PHONE>
<AREA>333</AREA>
<EXT></EXT>
</PHONENUMBER>
<EMAILADDRESS>
<EMAIL>test#test.com</EMAIL>
</EMAILADDRESS>
<CODE>
<ID>2</ID>
<DATE>2005-05-17</DATE>
<MEMO></MEMO>
</CODE>
<CODE>
<ID>3</ID>
<DATE>2005-05-17</DATE>
<MEMO></MEMO>
</CODE>
<COMMUNICATION>
<ID>6</ID>
<DATE>2005-05-17</DATE>
<MEMO></MEMO>
<TEXTAREA>details go here</TEXTAREA>
</COMMUNICATION>
<FINANCIAL>
<TYPE>contribution</TYPE>
<AMOUNT>150</AMOUNT>
<DATE>2005-05-17</DATE>
<CATEGORYID>3</CATEGORYID>
<THANKED>0</THANKED>
<CHECKNUMBER>Credit Card</CHECKNUMBER>
<MEMO></MEMO>
<CARDTYPE>VISA</CARDTYPE>
<CARDNUMBER>4444-4444-4444-4444</CARDNUMBER>
<CVV2>987</CVV2>
<EXPMONTH>02</EXPMONTH>
<EXPYEAR>2012</EXPYEAR>
</FINANCIAL>
</INDIVIDUAL>
</DATABASE>
I am not finding how to query multiple nodes as in my example.
You can try using this:
select
iqr_FirstName AS FIRSTNAME,
iqr_LastName AS LASTNAME,
iqr_Employer AS EMPLOYER,
iqr_Occupation AS OCCUPATION,
iqr_Line1 AS 'ADDRESS/ADR1',
iqr_City AS 'ADDRESS/CITY',
iqr_State AS 'ADDRESS/State',
iqr_Zip AS 'ADDRESS/ZIP',
iqr_CCAmount AS AMOUNT,
iqr_CreatedOn AS DATE
from
std7_ImportQueueRecord
for xml path('Individual')
to add extra structure (and XML elements) to your generated XML
My process involves getting a large XML file on a daily basis.
I have developed an SSIS package (2008 r2) which first gets rid of the multiple namespaces via a XSLT and then imports data into 40 tables (due to its complexity) by using the XML source object.
Here is the watered down version of a test xml file
<?xml version="1.0" encoding="UTF-8"?>
<s:Test xmlns:s="http://###.##.com/xml"
<sequence>62</sequence>
<generated>2015-04-28T00:59:38</generated>
<report_date>2015-04-27</report_date>
<orders>
<order>
</order>
</orders>
My question is: The XML source imports all the Orders with its nested attributes. How do I extract the 'report_date' and 'generated' from the header?
Any help would be much appreciated.
Thanks
SD
You can use XML method value() passing proper XPath/XQuery expression as parameter. For demo, consider the following table and data :
CREATE TABLE MyTable (id int, MyXmlColumn XML)
DECLARE #data XML = '<?xml version="1.0" encoding="UTF-8"?>
<s:Test xmlns:s="http://###.##.com/xml">
<sequence>62</sequence>
<generated>2015-04-28T00:59:38</generated>
<report_date>2015-04-27</report_date>
<orders>
<order>
</order>
</orders>
</s:Test>'
INSERT INTO Mytable VALUES(1,#data)
You can use the following query to get generated and report_date data :
SELECT
t.MyXmlColumn.value('(/*/generated)[1]','datetime') as generated
, t.MyXmlColumn.value('(/*/report_date)[1]','date') as report_date
FROM Mytable t
SQL Fiddle Demo
output :
generated report_date
----------------------- -----------
2015-04-28 00:59:38.000 2015-04-27
I am trying to figure out how I can insert a new line between fields in SQL Server 2008.
Current XML:
<products>
<product>
<ProductID>1</ProductID>
<ProductName>A.1</ProductName>
</product>
<product>
<ProductID>2</ProductID>
<ProductName>B.1</ProductName>
</product>
</products>
Desired XML:
<products>
<product>
<ProductID>1</ProductID>
<ProductName>A.1</ProductName>
</product>
<product>
<ProductID>2</ProductID>
<ProductName>B.1</ProductName>
</product>
</products>
Any ideas how I can inject Newline/carriage return in the XML output?
Any thoughts would be greatly appreciated.
Thanks,
S
Simple. Take the output, insert the lines. That is AFTER sql server.
This site has a technique to pass xml data around in Microsoft SQL Server:
DECLARE #productIds xml
SET #productIds ='<Products><id>3</id><id>6</id><id>15</id></Products>'
SELECT
ParamValues.ID.value('.','VARCHAR(20)')
FROM #productIds.nodes('/Products/id') as ParamValues(ID)
But what is the syntax if I add another field?
The following does NOT work:
DECLARE #productIds xml
SET #productIds ='<Products><id>3</id><descr>Three</descr><id>6</id><descr>six</descr><id>15</id><descr>Fifteen</descr></Products>'
SELECT
ParamValues.ID.value('.','VARCHAR(20)')
,ParamValues.descr.value('.','VARCHAR(20)')
FROM #productIds.nodes('/Products/id') as ParamValues(ID)
Note: Maybe I've constructed my xml wrong.
You need to use something like:
SELECT
ParamValues.ID.value('(id)[1]','VARCHAR(20)'),
ParamValues.ID.value('(descr)[1]','VARCHAR(20)')
FROM
#productIds.nodes('/Products') as ParamValues(ID)
That FROM statement there defines something like a "virtual table" called ParamValues.ID - you need to select the <Products> node into that virtual table and then access the properties inside it.
Furthermore, your XML structure is very badly chosen:
<Products>
<id>3</id>
<descr>Three</descr>
<id>6</id>
<descr>six</descr>
<id>15</id>
<descr>Fifteen</descr>
</Products>
You won't be able to select the individual pairs of id/descr - you should use something more like:
<Products>
<Product>
<id>3</id>
<descr>Three</descr>
</Product>
<Product>
<id>6</id>
<descr>six</descr>
</Product>
<Product>
<id>15</id>
<descr>Fifteen</descr>
</Product>
</Products>
Then you could retrieve all items using this SQL XML query:
SELECT
ParamValues.ID.value('(id)[1]','VARCHAR(20)') AS 'ID',
ParamValues.ID.value('(descr)[1]','VARCHAR(20)') AS 'Description'
FROM
#productIds.nodes('/Products/Product') as ParamValues(ID)
ID Descrition
3 Three
6 six
15 Fifteen
You must wrap each set of id and descr into one parent node. Say Row. Now you can access each pair like this.
DECLARE #productIds xml
SET #productIds ='<Products><Row><id>3</id><descr>Three</descr></Row><Row><id>6</id><descr>six</descr></Row><Row><id>15</id><descr>Fifteen</descr></Row></Products>'
SELECT
ParamValues.Row.query('id').value('.','VARCHAR(20)'),
ParamValues.Row.query('descr').value('.','VARCHAR(20)')
FROM #productIds.nodes('/Products/Row') as ParamValues(Row)