How to import below XML data into SQL Server table with three columns?
<dataset>
<metadata>
<item name="NAME_LAST" type="xs:string" length="62" />
<item name="NAME_FIRST" type="xs:string" length="62" />
<item name="NAME_MIDDLE" type="xs:string" length="32" />
</metadata>
<data>
<row>
<value>SMITH</value>
<value>MARY</value>
<value>N</value>
</row>
<row>
<value>SMITH2</value>
<value>MARY2</value>
<value>N2</value>
</row>
</data>
</dataset>
Try this:
DECLARE #input XML = '<dataset>
<metadata>
<item name="NAME_LAST" type="xs:string" length="62" />
<item name="NAME_FIRST" type="xs:string" length="62" />
<item name="NAME_MIDDLE" type="xs:string" length="32" />
</metadata>
<data>
<row>
<value>SMITH</value>
<value>MARY</value>
<value>N</value>
</row>
<row>
<value>SMITH2</value>
<value>MARY2</value>
<value>N2</value>
</row>
</data>
</dataset>'
INSERT INTO dbo.YourTable(ColName, ColFirstName, ColOther)
SELECT
Name = XCol.value('(value)[1]','varchar(25)'),
FirstName = XCol.value('(value)[2]','varchar(25)'),
OtherValue = XCol.value('(value)[3]','varchar(25)')
FROM
#input.nodes('/dataset/data/row') AS XTbl(XCol)
Insert XML Data into sql Server table
Declare #retValue1 varchar(50);
Declare #XmlStr XML;
SET #XmlStr='<Customers>
<customer>
<ID>111589</ID>
<FirstName>name1</FirstName>
<LastName>Lname1</LastName>
<Company>ABC</Company>
</customer>
<customer>
<ID>12345</ID>
<FirstName>name2</FirstName>
<LastName>Lname2</LastName>
<Company>ABC</Company>
</customer>
<customer>
<ID>14567</ID>
<FirstName>name3</FirstName>
<LastName>Lname3</LastName>
<Company>DEF</Company>
</customer>
</Customers>';
#retValue='Failed';
INSERT INTO [test_xmlinsert](
[id],
[firstName],
[lastName],
[company]
)
SELECT
COALESCE([Table].[Column].value('ID[1]', 'int'),0) as 'ID',
[Table].[Column].value('FirstName [1]', 'varchar(50)') as ' FirstName ',
[Table].[Column].value(' LastName[1]', 'varchar(50)') as ' LastName',
[Table].[Column].value(' Company [1]', 'varchar(50)') as ' Company'
FROM #XmlStr.nodes('/ Customers / customer') as [Table]([Column])
IF(##ROWCOUNT > 0 )
SET #retValue='SUCCESS';
Related
I need to insert an external XML file data into a SQL Server table. I tried the below code. But this inserts a single record with NULL values for all the columns
Declare #xml XML
Select #xml =
CONVERT(XML,bulkcolumn,2) FROM OPENROWSET(BULK
'C:\Users\PC901\Downloads\Tags.xml',SINGLE_BLOB) AS X
SET ARITHABORT ON
TRUNCATE TABLE Tags
Insert into Tags
(
ID,WikiPostId,ExcerptPostId,Count,TagName
)
Select
P.value('ID[1]','BIGINT') AS ID,
P.value('WikiPostId[1]','BIGINT') AS WikiPostId,
P.value('ExcerptPostId[1]','BIGINT') AS ExcerptPostId,
P.value('Count[1]','BIGINT') AS Count,
P.value('TagName[1]','VARCHAR(100)') AS TagName
From #xml.nodes('/tags') PropertyFeed(P)
SELECT * FROM Tags
and the sample XML would be
<?xml version="1.0" encoding="utf-8"?>
<tags>
<row Id="1" TagName=".net" Count="283778" ExcerptPostId="3624959" WikiPostId="3607476" />
<row Id="2" TagName="html" Count="826083" ExcerptPostId="3673183" WikiPostId="3673182" />
<row Id="3" TagName="javascript" Count="1817846" ExcerptPostId="3624960" WikiPostId="3607052" />
<row Id="4" TagName="css" Count="588062" ExcerptPostId="3644670" WikiPostId="3644669" />
<row Id="5" TagName="php" Count="1286873" ExcerptPostId="3624936" WikiPostId="3607050" />
</tags>
Here you go:
declare #xml xml = '<?xml version="1.0" encoding="utf-8"?>
<tags>
<row Id="1" TagName=".net" Count="283778" ExcerptPostId="3624959" WikiPostId="3607476" />
<row Id="2" TagName="html" Count="826083" ExcerptPostId="3673183" WikiPostId="3673182" />
<row Id="3" TagName="javascript" Count="1817846" ExcerptPostId="3624960" WikiPostId="3607052" />
<row Id="4" TagName="css" Count="588062" ExcerptPostId="3644670" WikiPostId="3644669" />
<row Id="5" TagName="php" Count="1286873" ExcerptPostId="3624936" WikiPostId="3607050" />
</tags>'
Select
P.value('#Id','BIGINT') AS ID,
P.value('#WikiPostId','BIGINT') AS WikiPostId,
P.value('#ExcerptPostId','BIGINT') AS ExcerptPostId,
P.value('#Count','BIGINT') AS Count,
P.value('#TagName','VARCHAR(100)') AS TagName
From #xml.nodes('/tags/row') PropertyFeed(P)
outputs
ID WikiPostId ExcerptPostId Count TagName
----------- -------------------- -------------------- -------------------- ----------
1 3607476 3624959 283778 .net
2 3673182 3673183 826083 html
3 3607052 3624960 1817846 javascript
4 3644669 3644670 588062 css
5 3607050 3624936 1286873 php
(5 rows affected)
I have a table EVENTS:
Name Event Gift Label
Jeff Birthday Card Happy Birthday
Jeff Birthday Present Jeff's prezzy
Maisey Promotion Cake Well Done!
Maisey Birthday Card Happy Birthday
Maisey Birthday Cake Another Year Older!
Here's the code to produce that table:
DECLARE #TempTable TABLE
(
[name] VARCHAR(250),
[event] VARCHAR(250),
[gift] VARCHAR(250),
[label] VARCHAR(2500)
);
INSERT INTO #TempTable([name], [event], [gift], [label]) VALUES
('Jeff','Birthday','Card','Happy Birthday'),
('Jeff','Birthday','Present','Jeff`s prezzy'),
('Maisey','Promotion','Cake','Well Done!'),
('Maisey','Birthday','Card','Happy Birthday'),
('Maisey','Birthday','Cake','Another Year Older!')
Which I would like to generate the following XML from:
<celebrations>
<person name="Jeff">
<events>
<event name="Birthday">
<gifts>
<gift name="Card" Value="Happy Birthday" />
<gift name="Present" Value="Jeff's prezzy" />
</gifts>
</event>
</events>
</person>
<person name="Maisey">
<events>
<event name="Promotion">
<gifts>
<gift name="Cake" value="Well Done!" />
</gifts>
</event>
<event name="Birthday">
<gifts>
<gift name="Card" value="Happy Birthday" />
<gift name="Cake" value="Another Year Older!" />
</gifts>
</event>
</events>
</person>
</celebrations>
My current SQLXML looks like this:
SELECT (
SELECT (
SELECT T1.*
FOR XML path('')
,root('gifts')
,type
)
FROM #TempTable AS T1
FOR XML path('person')
,type
)
FOR XML path('persons')
Which is currently producing this:
<persons>
<person>
<gifts>
<name>Jeff</name>
<event>Birthday</event>
<gift>Card</gift>
<label>Happy Birthday</label>
</gifts>
</person>
<person>
<gifts>
<name>Jeff</name>
<event>Birthday</event>
<gift>Present</gift>
<label>Jeff`s prezzy</label>
</gifts>
</person>
<person>
<gifts>
<name>Maisey</name>
<event>Promotion</event>
<gift>Cake</gift>
<label>Well Done!</label>
</gifts>
</person>
<person>
<gifts>
<name>Maisey</name>
<event>Birthday</event>
<gift>Card</gift>
<label>Happy Birthday</label>
</gifts>
</person>
<person>
<gifts>
<name>Maisey</name>
<event>Birthday</event>
<gift>Cake</gift>
<label>Another Year Older!</label>
</gifts>
</person>
</persons>
How do I format it to look like the XML in the portion at the top of this post?
Try this, the magic is the correlated sub-query with GROUP BY:
DECLARE #TempTable TABLE
(
[name] VARCHAR(250),
[event] VARCHAR(250),
[gift] VARCHAR(250),
[label] VARCHAR(2500)
);
INSERT INTO #TempTable([name], [event], [gift], [label]) VALUES
('Jeff','Birthday','Card','Happy Birthday'),
('Jeff','Birthday','Present','Jeff`s prezzy'),
('Maisey','Promotion','Cake','Well Done!'),
('Maisey','Birthday','Card','Happy Birthday'),
('Maisey','Birthday','Cake','Another Year Older!')
SELECT t1.[Name] AS [#name]
,(
SELECT T2.[Event] AS [#name]
,(
SELECT T3.gift AS [#name], T3.label AS [#value]
FROM #TempTable T3
WHERE T1.[Name]=T3.[Name] AND T2.[event] = T3.[event]
GROUP BY T3.gift, T3.label
FOR XML PATH('gift'),ROOT('gifts'),TYPE
)
FROM #TempTable T2
WHERE T1.[Name]=T2.[Name]
GROUP BY T2.[event]
FOR XML PATH('event'),ROOT('events'),TYPE
)
FROM #TempTable AS T1
GROUP BY t1.[Name]
FOR XML PATH('person'),ROOT('celebrations'),TYPE;
The result
<celebrations>
<person name="Jeff">
<events>
<event name="Birthday">
<gifts>
<gift name="Card" value="Happy Birthday" />
<gift name="Present" value="Jeff`s prezzy" />
</gifts>
</event>
</events>
</person>
<person name="Maisey">
<events>
<event name="Birthday">
<gifts>
<gift name="Cake" value="Another Year Older!" />
<gift name="Card" value="Happy Birthday" />
</gifts>
</event>
<event name="Promotion">
<gifts>
<gift name="Cake" value="Well Done!" />
</gifts>
</event>
</events>
</person>
</celebrations>
I have an XML file that looks like this:
<NodeA Type="A" Date="2015-10-28">
<NodeB Amount="0.00">
<Items />
</NodeB>
<NodeB Amount="0.00">
<Items>
<Item code="2" val="50.00" />
<Item code="8" val="50.00" />
</Items>
</NodeB>
</NodeA>
I am trying to use SQL Server and XPath to extract the child nodes of NodeA as XML.
Based on the above XML, I need to return a table with 2 rows, containing the following fields:
Type (nvarchar) | Date (Date) | ChildNode (XML)
-----------------------------------------------
A 2015-10-28 <NodeB Amount="0.00"><Items /></NodeB>
A 2015-10-28 <NodeB Amount="0.00"><Items>...</NodeB>
I know I can do this using C#, but is there a way to do this using XPath? I've some success with xPath returning the field values from NodeA, but can't seem to get NodeB to display as XML.
Try this -
DECLARE #xml AS XML
SET #xml = '<NodeA Type="A" Date="2015-10-28">
<NodeB Amount="0.00">
<Items />
</NodeB>
<NodeB Amount="0.00">
<Items>
<Item code="2" val="50.00" />
<Item code="8" val="50.00" />
</Items>
</NodeB>
</NodeA>'
SELECT c.value('(/NodeA/#Type)[1]', 'varchar(50)') AS Type,
c.value('(/NodeA/#Date)[1]', 'varchar(50)') AS Date,
c.query('.') AS ChildNodeXML
FROM #xml.nodes('/NodeA/NodeB') as T(C)
Result
Type Date ChildNodeXML
---- ------ ----------------------------------
A 2015-10-28 <NodeB Amount="0.00"><Items /></NodeB>
A 2015-10-28 <NodeB Amount="0.00"><Items><Item code="2" val="50.00" /><Item code="8" val="50.00" /></Items></NodeB>
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
I am writing SQL query to get output as below . I am not using any tables from database.
A query to get the desired output as
<Property ID="0" Name="Color" NumOfItems="11">
<Item ID="0" Name="D"/>
<Item ID="1" Name="E"/>
<Item ID="2" Name="F"/>
<Item ID="3" Name="G"/>
<Item ID="4" Name="H"/>
<Item ID="5" Name="I"/>
<Item ID="6" Name="J"/>
<Item ID="7" Name="K"/>
<Item ID="8" Name="L"/>
<Item ID="9" Name="M"/>
<Item ID="10" Name="N"/>
</Property>
I tried as this
SELECT
(
SELECT '0' AS 'Item/#ID','D' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '1' AS 'Item/#ID','E' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '2' AS 'Item/#ID','F' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '3' AS 'Item/#ID','G' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '4' AS 'Item/#ID','H' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '5' AS 'Item/#ID','I' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '6' AS 'Item/#ID','J' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '7' AS 'Item/#ID','K' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '8' AS 'Item/#ID','L' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '9' AS 'Item/#ID','M' AS 'Item/#Name' FOR XML PATH(''), TYPE ),
(SELECT '10' AS 'Item/#ID','N' AS 'Item/#Name' FOR XML PATH(''), TYPE )
FOR XML PATH(''),
ROOT('Property'),TYPE
I am not using any tables from database
Well just SELECT it...
SELECT CAST ('<Property ID="0" Name="Color" NumOfItems="11">
<Item ID="0" Name="D"/>
<Item ID="1" Name="E"/>
<Item ID="2" Name="F"/>
<Item ID="3" Name="G"/>
<Item ID="4" Name="H"/>
<Item ID="5" Name="I"/>
<Item ID="6" Name="J"/>
<Item ID="7" Name="K"/>
<Item ID="8" Name="L"/>
<Item ID="9" Name="M"/>
<Item ID="10" Name="N"/>
</Property>' AS XML)
1)
SELECT *
FROM (VALUES (0, 'Color', 11)) Property(ID, Name, NumOfItems)
JOIN (VALUES (0,0,'D'), (0,1,'E'), (0,2,'F')) Item(PropertyID,ID,Name)
ON Property.ID = Item.PropertyID
FOR XML AUTO
Output:
<Property ID="0" Name="Color" NumOfItems="11">
<Item PropertyID="0" ID="0" Name="D" />
<Item PropertyID="0" ID="1" Name="E" />
<Item PropertyID="0" ID="2" Name="F" />
</Property>
2)
SELECT *,
(SELECT * FROM (VALUES (0,'D'), (1, 'E'), (2, 'F')) MamboJambo("#ID", "#Name") FOR XML PATH('Item'),TYPE)
FROM (VALUES (0,'Color',11)) CocoJambo("#ID", "#Name", "#NumOfItems")
FOR XML PATH('Property')
3)
SELECT CONVERT(XML, N'<Property ID="0" Name="Color" NumOfItems="11">
<Item ID="0" Name="D"/>
<Item ID="1" Name="E"/>
<Item ID="2" Name="F"/>
</Property>').query(N'
for $x in (/Property)
return
<Property ID="{$x/#ID}" Name="{$x/#Name}" NumOfItems="{$x/#NumOfItems}" >
{for $y in ($x/Item) return $y}
</Property>
');
I'm writing a stored procedure to process XML data uploaded by the user:
<People>
<Person Id="1" FirstName="..." LastName="..." />
<Person Id="2" FirstName="..." LastName="..." />
<Person Id="3" FirstName="..." LastName="..." />
<Person Id="4" FirstName="..." LastName="..." />
<Person Id="5" FirstName="..." LastName="..." />
</People>
I would like to use a schema to make sure that the entities are valid, but I don't want the entire process to fail just because of one invalid entity. Instead, I would like to log all invalid entities to a table and process the valid entities as normal.
Is there a recommended way to do this?
A pure SQL approach would be:
Create a schema collection that defines <Person>:
CREATE XML SCHEMA COLLECTION [dbo].[testtest] AS
N'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Person">
<xs:complexType>
<xs:attribute name="Id" type="xs:int" use="required"/>
<xs:attribute name="FirstName" type="xs:string" use="required"/>
<xs:attribute name="LastName" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
'
(one-time operation)
Have an XML query that selects each <Person> node from <People> as a separate row.
Declare a cursor on that query and select each row into an untyped xml variable. After the select, try to assign to a typed xml variable from within a try-catch block.
Resulting code would look like:
declare #source xml = N'
<People>
<Person Id="1" FirstName="..." LastName="..." />
<Person Id="2" FirstName="..." LastName="..." />
<Person Id="f" FirstName="..." LastName="..." />
<Person Id="4" FirstName="..." LastName="..." />
<Person Id="5" FirstName="..." LastName="..." />
</People>';
declare foo cursor
local
forward_only
read_only
for
select t.p.query('.')
from #source.nodes('People/Person') as t(p)
;
declare #x xml (dbo.testtest);
declare #x_raw xml;
open foo;
fetch next from foo into #x_raw;
while ##fetch_status = 0
begin
begin try
set #x = #x_raw;
print cast(#x_raw as nvarchar(max)) + ': OK';
end try
begin catch
print cast(#x_raw as nvarchar(max)) + ': FAILED';
end catch;
fetch next from foo into #x_raw;
end;
close foo;
deallocate foo;
Result:
<Person Id="1" FirstName="..." LastName="..."/>: OK
<Person Id="2" FirstName="..." LastName="..."/>: OK
<Person Id="f" FirstName="..." LastName="..."/>: FAILED
<Person Id="4" FirstName="..." LastName="..."/>: OK
<Person Id="5" FirstName="..." LastName="..."/>: OK
A simpler option is to create a CLR stored procedure that would parse XML in a .NET language.