Unable to read data into SQL Server 2005 from an XML file - sql

I am trying to use the following script to read data from an XML file and insert it into a table called TermsTree on SQL Server 2005.
INSERT INTO TermsTree (TermID,ParentID,Name)
SELECT X.TermsTree.query('TermID').value('.', 'INT'),
X.TermsTree.query('ParentID').value('.', 'INT'),
X.TermsTree.query('Name').value('.', 'VARCHAR(2000)')
FROM (
SELECT CAST(x AS XML)
FROM OPENROWSET(
BULK 'C:\Users\MehtabM\Desktop\GetAllTermTree.xml',
SINGLE_BLOB) AS T(x)
) AS T(x)
CROSS APPLY x.nodes('ArrayOfTerm_Child/Term_Child') AS X(TermsTree);
A sample of the XML file is
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfTerm_Child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Term_Child>
<TermID>2021</TermID>
<Name>A. Geographic locations</Name>
<ParentID>0</ParentID>
</Term_Child>
<Term_Child>
<TermID>3602</TermID>
<Name>Oceania</Name>
<ParentID>2021</ParentID>
</Term_Child>
<Term_Child>
<TermID>3604</TermID>
<Name>Australasia</Name>
<ParentID>3602</ParentID>
</Term_Child>
</Term_Child>
</ArrayOfTerm_Child>

http://www.sqlfiddle.com/#!3/18f84/15
declare #xml xml
select #xml='<?xml version="1.0" encoding="utf-8"?>
<ArrayOfTerm_Child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Term_Child>
<TermID>2021</TermID>
<Name>A. Geographic locations</Name>
<ParentID>0</ParentID>
</Term_Child>
<Term_Child>
<TermID>3602</TermID>
<Name>Oceania</Name>
<ParentID>2021</ParentID>
</Term_Child>
<Term_Child>
<TermID>3604</TermID>
<Name>Australasia</Name>
<ParentID>3602</ParentID>
</Term_Child>
</ArrayOfTerm_Child>'
;WITH XMLNAMESPACES(DEFAULT 'http://tempuri.org/')
SELECT X.TermsTree.query('TermID').value('.', 'INT'),
X.TermsTree.query('ParentID').value('.', 'INT'),
X.TermsTree.query('Name').value('.', 'VARCHAR(2000)')
FROM #xml.nodes('/ArrayOfTerm_Child/Term_Child') X(TermsTree)

Related

How to insert with namespace

U have a XML file. I want to add this data to an SQL table. But something is wrong with the namespace. But I don't know what. please help me.
<?xml version="1.0" encoding="utf-8"?>
<sl:bagStand>
<Customer>
<Document>000 000 000</Document>
<names>
<Name>Mary Angel</Name>
</names>
<Address>Your City, YC 1212</Address>
<prop><Profession>Systems Analyst</Profession></prop>
</Customer>
</sl:bagStand>
I want to run this insert query
;WITH XMLNAMESPACES('sl' as x)
INSERT INTO CUSTOMERS_TABLE (DOCUMENT, NAME, ADDRESS, PROFESSION)
SELECT
MY_XML.Customer.query('Document').value('.', 'VARCHAR(20)'),
MY_XML.Customer.query('Name').value('.', 'VARCHAR(50)'),
MY_XML.Customer.query('Address').value('.', 'VARCHAR(50)'),
MY_XML.Customer.query('Profession').value('.', 'VARCHAR(50)')
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\temp\MSSQLTIPS_XML.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('x:bagStand/Customer') AS MY_XML (Customer);
Now i get a error:
Msg 9459, Level 16, State 1, Line 1
XML parsing: line 2, character 13, undeclared prefix
what am i doing wrong?

Add XML attribute in mssql using stored procedure

i want output
<CustomerName>
<Customer id='1'>
<Name>xyz</Name>
</Customer>
<Customer id='2'>
<Name>Abc</Name>
</Customer>
</CustomerName>
for this output i wrote SP
SELECT
'' AS [CustomerName],
(SELECT
Name[Customer/Name]
FOR XML PATH(''), TYPE) AS[CustomerName/Customer]
FOR XML PATH('')
not able to add Id attribute, please help me
Try this:
DECLARE #tblCust TABLE(id INT, CustomerName VARCHAR(100));
INSERT INTO #tblCust VALUES
(1,'xyz')
,(2,'Abc');
SELECT id AS [#id]
,CustomerName AS [Name]
FROM #tblCust
FOR XML PATH('Customer'),ROOT('CustomerName')
This is the result
<CustomerName>
<Customer id="1">
<Name>xyz</Name>
</Customer>
<Customer id="2">
<Name>Abc</Name>
</Customer>
</CustomerName>
SELECT [#id] = t.id, [Name] = t.name
FROM (
VALUES (1, 'name'), (2, 'name2')
) t (id, name)
FOR XML PATH('Customer'), ROOT('CustomerName')

How do I select the node values from the following XML using SQL?

I have the following:
DECLARE #XML XML
SET #XML = '<?xml version="1.0" encoding="utf-8"?>
<member xmlns="http:...xsd" xmlns:xsi="http:...XMLSchema-instance">
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
</member>
I have a table with the following columns:
Member
Person
Name
LastName
How do I go about adding the values from the XML to my table?
If I'm not mistaken I'd have to do a CROSS APPLY but im not sure how to do this.
You can use something like this:
DECLARE #XML XML
SET #XML = '<?xml version="1.0" encoding="utf-8"?>
<member xmlns="http://testxsd" xmlns:xsi="http:...XMLSchema-instance">
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
</member>'
;WITH XMLNAMESPACES(DEFAULT 'http://testxsd')
SELECT
PersonName = XPerson.value('(Name)[1]', 'varchar(50)'),
PersonLastName = XPerson.value('(LastName)[1]', 'varchar(50)')
FROM #XML.nodes('/member/Person') AS XTbl(XPerson)
which will give you an output of:
And of course, if you want to insert that data into a table, you can use:
;WITH XMLNAMESPACES(DEFAULT 'http://testxsd')
INSERT INTO dbo.Person(Name, LastName)
SELECT
PersonName = XPerson.value('(Name)[1]', 'varchar(50)'),
PersonLastName = XPerson.value('(LastName)[1]', 'varchar(50)')
FROM #XML.nodes('/member/Person') AS XTbl(XPerson)

How to read an attribute of the XML

DECLARE #XmlData xml
SET #XmlData= '<?xml version="1.0" encoding="utf-8" ?>
<ROOT PROCESS_DATE="25-Nov-2009" ROW_COUNT="2" VERIFY_TOTAL="654454.54">
<row rowNumber="1">
<Code1>11111</Code1>
<Code2>AAAA </Code2>
</row>
<row rowNumber="2">
<Code1>2222</Code1>
<Code2>BBBB </Code2>
</row>
</ROOT>'
-- Following query returns the Code1, & Code2 for each row.
SELECT
R.i.query('Code1').value('.', 'nvarchar(8)') AS Code1,
R.i.query('Code2').value('.', 'nvarchar(8)') AS Code2
FROM #XmlData.nodes('/ROOT/row') R(i)
-- Now I want to get the rowNumber attribute of each row in the resultset.
SELECT
R.i.query('#rowNumber') AS rowNumber,
R.i.query('Code1').value('.', 'nvarchar(8)') AS Code1,
R.i.query('Code2').value('.', 'nvarchar(8)') AS Code2
FROM #XmlData.nodes('/ROOT/row') R(i)
-- Above query returns error
DECLARE #x XML ;
SET #x = '<?xml version="1.0" encoding="utf-8" ?>
<ROOT PROCESS_DATE="25-Nov-2009" ROW_COUNT="2" VERIFY_TOTAL="654454.54">
<row rowNumber="1">
<Code1>11111</Code1>
<Code2>AAAA </Code2>
</row>
<row rowNumber="2">
<Code1>2222</Code1>
<Code2>BBBB </Code2>
</row>
</ROOT>' ;
SELECT v.value('.', 'VARCHAR(20)') AS Name
FROM #x.nodes('(/ROOT/row/#*)') x ( v )
I don't have SQL Server handy, but my instincts tell me to try:
R.i.query('.').value('#rowNumber', 'int') AS rowNumber
You can query the attribute with the data() workaround:
R.i.query('data(row/#Name)').value('.','int') AS rowNumber

How to insert xml into a node in another xml using XQuery?

I have two xml variable say #res, #student in a stored proc in SQL server 2005.
#res contains
<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>
#student contains:
<Student>
<Name>XYZ</Name>
<Roll>15</Roll>
<Result />
<Attendance>50</Attendance>
</Student>
I need to insert the xml of #res into the node Result in #student variable using XQuery.
How to implement that?
Please help.
In SQL Server 2008, it's pretty easy:
DECLARE #res XML = '<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>'
DECLARE #student XML = '<Student>
<Name>XYZ</Name>
<Roll>15</Roll>
<Result />
<Attendance>50</Attendance>
</Student>'
SET #student.modify('insert sql:variable("#res") as first into (/Student/Result)[1]')
SELECT #student
That gives me the output:
<Student>
<Name>XYZ</Name>
<Roll>15</Roll>
<Result>
<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>
</Result>
<Attendance>50</Attendance>
</Student>
Unfortunately, the ability to call .modify() and use a sql:variable in the insert statement was introduced with SQL Server 2008 only - doesn't work in SQL Server 2005.
I don't see how you could do this in SQL Server 2005, other than resorting back to ugly string parsing and replacement:
SET #student =
CAST(REPLACE(CAST(#student AS VARCHAR(MAX)),
'<Result/>',
'<Result>' + CAST(#res AS VARCHAR(MAX)) + '</Result>') AS XML)
Marc
This will work in SQL 2005 and is mostly an xquery solution:
DECLARE #res xml
SET #res =
'<Subject>English</Subject>
<Marks>67</Marks>
<Subject>Science</Subject>
<Marks>75</Marks>'
DECLARE #student xml
SET #student =
'<Student>
<Name>XYZ</Name>
<Roll>15</Roll>
<Result />
<Attendance>50</Attendance>
</Student>'
DECLARE #final XML
SET #final = CAST(CAST(#student AS VARCHAR(MAX)) + '<test>' + CAST(#res AS VARCHAR(MAX)) + '</test>' AS XML)
SET #final.modify('insert /test/* into (/Student/Result)[1]')
SET #final.modify('delete /test')
SELECT #final
You can set your #student variable to #final at that point if you need to do that. The name of "test" for the node was just what I chose to use. You can use any name as long as it will not already appear in your XML.
You basically just throw the two XML strings together so that they are both available to xquery at once.
You may also try to go back to relational data and than back to xml; something like:
DECLARE #res xml =
'<result>
<StudentID>1</StudentID>
<Subject>English</Subject>
<Marks>67</Marks>
</result>
<result>
<StudentID>1</StudentID>
<Subject>Science</Subject>
<Marks>75</Marks>
</result>'
DECLARE #student xml =
'<Student>
<StudentID>1</StudentID>
<Name>XYZ</Name>
<Roll>15</Roll>
<Attendance>50</Attendance>
</Student>'
;
WITH cte_1
AS ( SELECT t.c.value('StudentID[1]', 'int') AS [StudentID]
,t.c.value('Subject[1]', 'varchar(50)') AS [Subject]
,t.c.value('Marks[1]', 'int') AS [Marks]
FROM #res.nodes('/result') AS t ( c )
),
cte_2
AS ( SELECT t.c.value('StudentID[1]', 'int') AS [StudentID]
,t.c.value('Name[1]', 'varchar(50)') AS [Name]
,t.c.value('Roll[1]', 'int') AS [Roll]
,t.c.value('Attendance[1]', 'int') AS [Attendance]
FROM #student.nodes('/Student') AS t ( c )
)
SELECT student.StudentID
,student.[Name]
,student.Roll
,student.Attendance
,( SELECT result.[Subject]
,result.Marks
FROM cte_1 AS result
WHERE student.StudentID = result.StudentID
FOR
XML AUTO
,TYPE
,ELEMENTS
)
FROM cte_2 AS student
FOR XML AUTO
,ELEMENTS
Returns:
<student>
<StudentID>1</StudentID>
<Name>XYZ</Name>
<Roll>15</Roll>
<Attendance>50</Attendance>
<result>
<Subject>English</Subject>
<Marks>67</Marks>
</result>
<result>
<Subject>Science</Subject>
<Marks>75</Marks>
</result>
</student>
Not exactly your example, but close.