Parse XML in SQL Server resulting in NULLs - sql

I'm trying to parse an XML file in a SQL Server 2014 stored procedure.
The XML file looks like this:
<PROJECTS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<APPLICATION_ID>9204797</APPLICATION_ID>
<ACTIVITY>R44</ACTIVITY>
<ADMINISTERING_IC>AI</ADMINISTERING_IC>
<APPLICATION_TYPE>5</APPLICATION_TYPE>
<ARRA_FUNDED>N</ARRA_FUNDED>
<AWARD_NOTICE_DATE>01/11/2017</AWARD_NOTICE_DATE>
<BUDGET_START>01/01/2017</BUDGET_START>
<BUDGET_END>12/31/2017</BUDGET_END>
</row>
</PROJECT>
And my code is
SELECT
nref.value('#APPLICATION_ID[1]','varchar(max)') APPLICATION_ID,
nref.value('#ACTIVITY[1]','varchar(max)') ACTIVITY
FROM
[ADMIN_Grant_Exporter_Files_XML]
CROSS APPLY
XMLData.nodes('//PROJECT/row') as R(nref)
WHERE
APPLICATION_ID = '9204797'
APPLICATION_ID is stored as a separate column in the table.
I have tried
XMLData.nodes('//PROJECT/row')
and all combinations such as
XMLData.nodes('//PROJECT[1]')
XMLData.nodes('//row[1]')
Any help is appreciated. All I get back are nulls even if I remove the WHERE because I only have one record in the table at this point.

Root tag(PROJECTS) spelling is wrong in nodes method. Then to extract APPLICATION_ID you need to use value method like this.
nref.value('(APPLICATION_ID)[1]', 'Int')
# is used in value method to read attributes but APPLICATION_ID is a element in your xml
also you cannot use the alias name in same select queries Where clause
DECLARE #xml XML ='<PROJECTS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<APPLICATION_ID>9204797</APPLICATION_ID>
<ACTIVITY>R44</ACTIVITY>
<ADMINISTERING_IC>AI</ADMINISTERING_IC>
<APPLICATION_TYPE>5</APPLICATION_TYPE>
<ARRA_FUNDED>N</ARRA_FUNDED>
<AWARD_NOTICE_DATE>01/11/2017</AWARD_NOTICE_DATE>
<BUDGET_START>01/01/2017</BUDGET_START>
<BUDGET_END>12/31/2017</BUDGET_END>
</row>
</PROJECTS>' -- Here PROJECT should be PROJECTS
SELECT nref.value('(APPLICATION_ID)[1]', 'Int') APPLICATION_ID,
nref.value('(ACTIVITY)[1]', 'varchar(max)') ACTIVITY
FROM #xml.nodes('//PROJECTS/row') AS R(nref) -- Here PROJECT should be PROJECTS
WHERE nref.value('(APPLICATION_ID)[1]', 'Int') = 9204797

Related

Querying XML tag in SQL server

I have a table Student with a column studentStateinfo which consist of XML value as below.
<params xmlns="">
<OldStudentID>1aedghe1d8ef</OldStudentID>
</params>
Now when I query this table Student I only want to check whether studentStateinfo column have an XML data with tag <OldStudentID>
Use the exist() Method (xml Data Type)
Example using a variable, you should change that to a column instead.
declare #X xml = '
<params xmlns="">
<OldStudentID>1aedghe1d8ef</OldStudentID>
</params>';
select #X.exist('/params/OldStudentID');

Extracting XML data from NCLOB from XML with attributes in Oracle db

I am trying to extract values from XML data stored as NCLOB column in Oracle db table.
xml structure
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://example.com/FAS/DOC/2011/v3.0b" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<record xmlns="http://example.com/FAS/DOC/2011/v3.0b">
<pdate xmlns="http://example.com/FAS/DOC/2011/v3.0b">2014-05-15</pdate>
</record>
</root>
Query
select EXTRACTVALUE(XMLTYPE(nclob_column),'/root/record/pdate','xmlns="http://example.com/FAS/DOC/2011/v3.0b"') pdate1,
EXTRACTVALUE(XMLTYPE(nclob_column),'/root/record/pdate') pdate2
from nclob_table
Problem
The pdate1 does return the value, but pdate2 returns null. I
cannot use the third parameter of EXTRACTVALUE() to specify the xmlns
attribute value as that changes on every row/record. So I get the
value for one row but null for all others.
How do I extract the value without specifying the attribute?
Thanks.
If you can guarantee that the namespace doesn't matter for selecting an element in this case, you can use local-name() to match element only by it's local name, ignoring the namespace :
select EXTRACTVALUE(
XMLTYPE(nclob_column),
'/*[local-name()="root"]/*[local-name()="record"]/*[local-name()="pdate"]'
) pdate
from nclob_table
SQL Fiddle

How to add attributes to an existing xml string stored as a field from the rest of the columns in the same row using SQL

My question is tough to explain so let me give you a visual. First, I have this view to work with:
I have the XML in the AuditValue column. I want to add every other column to the XML column as attributes. So my first row would look like this:
<row ManufacturerID="6"
ManufacturerName="AMES999"
IsDeleted="0" Concurrency="AAAAAAABTAk="
EntryID="1"
TableName="Manufacturers"
AuditDate="2013-01-30 15:48:24.69" ChangeType="U"/>
I would like to do this dynamically. Semantically, I mean: For every column in the view except for the AuditValue column, add the column to the AuditValue column XML as an attribute.
I am SQL stupid for the most part. I know the basics, but that is about it. Help would be most appreciated. Any more info I can or need to provide, please let me know. I'm happy to provide anything needed.
I have found no way to add the attributes to existing nodes in a query. You could of course create a temporary table from your table and modify the XML in the temporary table adding one attribute at a time.
Another option would be to accept the fact that this is hard and decide that you want to build an XML that has all the data but not in the exact way you want. For example this query.
select *
from YourTable
for xml raw
Will give you XML like this.
<row EntryID="1" TableName="Manufacturers" AuditDate="2013-01-30T15:48:24.690" ChangeType="U">
<AuditValue>
<row ManufacturerID="6" ManufacturerName="AMES999" IsDeleted="0" Concurrency="AAAAAAABTAk=" />
</AuditValue>
</row>
Or you could use this
select EntryID as '#EntryID',
TableName as '#TableName',
AuditDate as '#AuditDate',
ChangeType as '#ChangeType',
AuditValue as '*'
from YourTable
for xml path('row')
to get the XML
<row EntryID="1" TableName="Manufacturers" AuditDate="2013-01-30T15:48:24.690" ChangeType="U">
<row ManufacturerID="6" ManufacturerName="AMES999" IsDeleted="0" Concurrency="AAAAAAABTAk=" />
</row>
If you are ready to get really ugly with this you can try a combination of XML and string manipulation.
select cast(replace(cast(AuditValue as nvarchar(max)), '/>', '') +
stuff(cast((
select EntryID, TableName, AuditDate, ChangeType
for xml raw, type
) as nvarchar(max)) ,1 , 4, '') as xml) as AuditValue
from YourTable
Result:
<row ManufacturerID="6"
ManufacturerName="AMES999"
IsDeleted="0"
Concurrency="AAAAAAABTAk="
EntryID="1"
TableName="Manufacturers"
AuditDate="2013-01-30T15:48:24.690"
ChangeType="U" />
SQL Fiddle

FOR XML AUTO and sql server 2005

SELECT * FROM emp FOR XML AUTO , ROOT ('Employees') , ELEMENTS
this query return value in xml format but total xml is showing in one column and column name is showing dynamically. if i want that i will specify the column name like data etc. so xml value will show as single row & column but header or output column name will be "DATA"
is it possible if yes the please show me the way.thanks
You need to check out the new FOR XML PATH feature in SQL Server 2005 and up - read all about it in SQL Server Books Online.
Basically, with FOR XML PATH, you can define the shape of your XML very easily, e.g.
SELECT
EmployeeID AS '#EmployeeID',
FirstName,
LastName
FROM dbo.Employees
FOR XML PATH('Employee'), ROOT('AllEmployees')
will generate XML something like:
<AllEmployees>
<Employee EmployeeID="12345">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Employee>
</AllEmployees>
FOR XML PATH is very flexible and allows you to do a lot of things quite easily and intuitively.

XML data type and Sql server 2005

i have one table where one field type is xml and there data is saved in xml format. my xml is
<Record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DELETED>
<STOCK_CODE>111111</STOCK_CODE>
<MakeID>GB00000001</MakeID>
<ModelID>GB00000001</ModelID>
<EngineSize />
<YearMakeFrom>0</YearMakeFrom>
<YearMakeTo>0</YearMakeTo>
<Automatic>1</Automatic>
<SemiAutomatic>1</SemiAutomatic>
<Manual>0</Manual>
<OtherInfo />
<Status>UPDATED</Status>
</DELETED>
</Record>
so please tell me how could i query the above xml document in sql server 2005. please help. thanks.
You're not saying what you're looking for exactly - so here's just a guess.
Assume you have a table full of rows, each row has a XML column XmlData which contains the above structure, and you want to get the Stock_Code and ModelID from that XML.
In that case, you'd use something like this:
SELECT
ID,
XmlData.value('(/Record/DELETED/STOCK_CODE)[1]', 'BIGINT') AS 'StockCode',
XmlData.value('(/Record/DELETED/ModelID)[1]', 'VARCHAR(25)') AS 'ModelID'
FROM
dbo.YourTable
WHERE
(some condition)
Is that what you're looking for?? If not: please clarify your question!