How to fetch XML node value with namespace in sql server? - sql

I have to get values of company node elements.I have tried all the
method to fetch data from the node but no luck. Below is my XML.
<?xml version="1.0"?>
<CompanyInvoice xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Customer xmlns="http://t.service/CompanyServices/">
<Company>
<CompanyId>10001</CompanyId>
<CoastalId>454564564564564564564564565465454546565555555</CoastalId>
<CompanyFederalId>345345</CompanyFederalId>
<CompanyName>Anytime Home</CompanyName>
<CompanyAddress>Address1</CompanyAddress>
<CompanyCity>TR</CompanyCity>
<CompanyState>UT</CompanyState>
<CompanyPostalCode>11</CompanyPostalCode>
<CompanyCountry>IT</CompanyCountry>
<CompanyTelephone>(999) 999-9999</CompanyTelephone>
</Company>
<CustomerId>33642</CustomerId>
</Customer>
</CompanyInvoice>
TSQL Code:
I have simply tried with this, but not getting any updates
Declare #DATAXML xml ='<?xml version="1.0"?>
<CompanyInvoice xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Customer xmlns="http://t.service/CompanyServices/">
<Company>
<CompanyId>10001</CompanyId>
<CoastalId>454564564564564564564564565465454546565555555</CoastalId>
<CompanyFederalId>345345</CompanyFederalId>
<CompanyName>Anytime Home</CompanyName>
<CompanyAddress>Address1</CompanyAddress>
<CompanyCity>TR</CompanyCity>
<CompanyState>UT</CompanyState>
<CompanyPostalCode>11</CompanyPostalCode>
<CompanyCountry>IT</CompanyCountry>
<CompanyTelephone>(999) 999-9999</CompanyTelephone>
</Company>
<CustomerId>33642</CustomerId>
</Customer>
</CompanyInvoice>'
;WITH XMLNAMESPACES('http://t.service/CompanyServices/' as x)
Select
a.value('x:CompanyId[1]','nvarchar(50)') as CompanyId,
a.value('x:CoastalId[1]','nvarchar(500)') as CoastalId,
a.value('x:CompanyName[1]','nvarchar(500)') as CompanyName
From #DATAXML.nodes('/CompanyInvoice/Customer/Company')as a (a)

Basically you have two options.
1.Introduce and use namespaces properly. Pay attention to namespaces scope.
2.Use a wildcard namespace (not recommended in production)
Declare #DATAXML xml = N'<?xml version="1.0"?>
<CompanyInvoice xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Customer xmlns="http://t.service/CompanyServices/">
<Company>
<CompanyId>10001</CompanyId>
<CoastalId>454564564564564564564564565465454546565555555</CoastalId>
<CompanyFederalId>345345</CompanyFederalId>
<CompanyName>Anytime Home</CompanyName>
<CompanyAddress>Address1</CompanyAddress>
<CompanyCity>TR</CompanyCity>
<CompanyState>UT</CompanyState>
<CompanyPostalCode>11</CompanyPostalCode>
<CompanyCountry>IT</CompanyCountry>
<CompanyTelephone>(999) 999-9999</CompanyTelephone>
</Company>
<CustomerId>33642</CustomerId>
</Customer>
</CompanyInvoice>';
WITH XMLNAMESPACES('http://t.service/CompanyServices/' as x)
Select
a.value('x:CompanyId[1]','nvarchar(50)') as CompanyId,
a.value('x:CoastalId[1]','nvarchar(500)') as CoastalId,
a.value('x:CompanyName[1]','nvarchar(500)') as CompanyName
From #DATAXML.nodes('CompanyInvoice/x:Customer/x:Company')as a (a);
--
select t.node.value('*:CompanyId[1]', 'int')
from #DATAXML.nodes('*:CompanyInvoice/*:Customer/*:Company') t(node);

Try This this just and other example
REferThis for more info
DECLARE #foo XML
SELECT #foo = N'
<harrys>
<harry>
<fish>0.015000000000</fish>
<bicycle>2008-10-31T00:00:00+01:00</bicycle>
<foo>ü</foo>
</harry>
<harry>
<fish>0.025000000000</fish>
<bicycle>2008-08-31T00:00:00+01:00</bicycle>
<foo>ä</foo>
</harry>
</harrys>
'
SELECT
CAST(CAST(y.item.query('data(fish)') AS varchar(30)) AS float),
CAST(LEFT(CAST(y.item.query('data(bicycle)') AS char(25)), 10) AS smalldatetime),
CAST(y.item.query('data(foo)') AS varchar(25))
FROM
#foo.nodes('/*') x(item)
CROSS APPLY
x.item.nodes('./*') AS y(item)
SELECT
CAST(CAST(x.item.query('data(fish)') AS varchar(30)) AS float),
CAST(LEFT(CAST(x.item.query('data(bicycle)') AS char(25)), 10) AS smalldatetime),
CAST(x.item.query('data(foo)') AS varchar(25))
FROM
#foo.nodes('harrys/harry') x(item)
SELECT
CAST(CAST(y.item.query('data(fish)') AS varchar(30)) AS float),
CAST(LEFT(CAST(y.item.query('data(bicycle)') AS char(25)), 10) AS smalldatetime),
CAST(y.item.query('data(foo)') AS varchar(25))
FROM
#foo.nodes('/harrys') x(item)
CROSS APPLY
x.item.nodes('./harry') AS y(item)
If this dosent work then
Alternate Link

Related

Parse selected values from XML in SQL

I have the following XML file (I put here only a short scheme), it's a SEPA XML bank statement. I'm not familiar with parsing XML files, my next move will be inserting and comparing to data stored in the SQL databases for error checks. Sadly, I know what to do next, don't know how to make progress with my first step. All I need is to create a table to select values of 2 attributes from a file stored at a particular place
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
<GrpHdr>
..........
</GrpHdr>
<Stmt>
<Ntry>
<Amt Ccy="EUR">RequestedAmount1</Amt>
<AddtlNtryInf>RequestedInfo1</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount2</Amt>
<AddtlNtryInf>RequestedInfo2</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount3</Amt>
<AddtlNtryInf>RequestedInfo3</AddtlNtryInf>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>
If the XML structure was simpler, for example like this...
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Ntry>
<Amt Ccy="EUR">RequestedAmount1</Amt>
<AddtlNtryInf>RequestedInfo1</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount2</Amt>
<AddtlNtryInf>RequestedInfo2</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount3</Amt>
<AddtlNtryInf>RequestedInfo3</AddtlNtryInf>
</Ntry>
...then I'd use this query to select requested attributes Amt and AddtlNtryInf and it works perfectly
SELECT
MY_XML.Ntry.query('Amt').value('.', 'NVARCHAR(255)') AS Amt,
MY_XML.Ntry.query('AddtlNtryInf').value('.', 'NVARCHAR(255)') AS AddtlNtryInf
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\tmp\TestSqlSimple.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('Ntry') AS MY_XML (Ntry);
But don't know how to deal with that more complicated one. I've tried something like this and several similar attempts but I failed because it doesn't select anything, the result is nothing
SELECT
MY_XML.Ntry.query('Amt').value('.', 'NVARCHAR(255)') AS Amt,
MY_XML.Ntry.query('AddtlNtryInf').value('.', 'NVARCHAR(255)') AS AddtlNtryInf
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\tmp\TestSqlSimple.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('/Document/BkToCstmrStmt/Stmt/Ntry') AS MY_XML (Ntry);
Can't figure out what to do with that CROSS APPLY. Thank you very much for any suggestions or improvements, you're doing a great job
You were almost there.
(1) The XML file has a default namespace, and it needs a special treatment via XMLNAMESPACES clause.
(2) The Amt element probably has a numeric value so you could use DECIMAL(x,y) data type. But I kept the NVARCHAR(255) to match the obfuscated XML file example.
(3) The SQL below is using .value() method without unnecessary .query() method.
(4) It is a good practice to use elementName/text() technique for performance reasons. It is MS SQL Server specific peculiarity.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (
ID INT IDENTITY PRIMARY KEY,
Amt NVARCHAR(255),
AddtlNtryInf NVARCHAR(255)
);
-- DDL and sample data population, end
;WITH XMLNAMESPACES (DEFAULT 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02')
, XmlFile (xmlData) AS
(
SELECT TRY_CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK 'e:\Temp\TestSqlSimple.xml', CODEPAGE = '65001', SINGLE_BLOB) AS x
)
INSERT INTO #tbl (Amt, AddtlNtryInf)
SELECT c.value('(Amt/text())[1]', 'NVARCHAR(255)') AS Amt
, c.value('(AddtlNtryInf/text())[1]', 'NVARCHAR(255)') AS AddtlNtryInf
FROM XmlFile CROSS APPLY xmlData.nodes('/Document/BkToCstmrStmt/Stmt/Ntry') AS t(c);
-- test
SELECT * FROM #tbl;
Something like this:
declare #doc xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
<GrpHdr>
..........
</GrpHdr>
<Stmt>
<Ntry>
<Amt Ccy="EUR">RequestedAmount1</Amt>
<AddtlNtryInf>RequestedInfo1</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount2</Amt>
<AddtlNtryInf>RequestedInfo2</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount3</Amt>
<AddtlNtryInf>RequestedInfo3</AddtlNtryInf>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>';
with xmlnamespaces (DEFAULT 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02')
select s.Stmt.value('(GrpHdr)[1]', 'varchar(200)') GrpHdr,
n.Ntry.value('(Amt)[1]', 'varchar(200)') Amt,
n.Ntry.value('(AddtlNtryInf)[1]', 'varchar(200)') AddtlNtryInf
from #doc.nodes('/Document/BkToCstmrStmt') s(Stmt)
outer apply s.Stmt.nodes('Stmt/Ntry') n(Ntry)

How to get value from ntext (in xml format) column in sql

I have a column in my SQL database that is called Triggers_xml_data and its type is ntext. The column is in a xml format and I am trying to get a value from a certain part of the xml. I seen an example of this being done without a column like this:
declare #fileContent xml
set #fileContent ='<my:Header>
<my:Requestor>Mehrlein, Roswitha</my:Requestor>
<my:RequestorUserName>SJM\MehrlR01</my:RequestorUserName>
<my:RequestorEmail>RMehrlein#SJM.com</my:RequestorEmail>
<my:HRContact>Roswita Mehrlein, Beatrice Porta</my:HRContact>
<my:Entity>SJM Germany</my:Entity>
<my:Department>HR/Administration</my:Department>
<my:PositionTitle>Sales Representative</my:PositionTitle>
<my:JobDescription>x0lGQRQAAAABAAAAAAAAAAAeAQAyAAAAVgBAAAAA=</my:JobDescription>
<my:PositionDepartment>Sales</my:PositionDepartment>'
 
;WITH XMLNAMESPACES ('http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-08-29T12-58-51' as my)
select #fileContent.value('(//my:PositionDepartment)[1]', 'varchar(255)')
But I want to select my column like this:
Declare #filevalue xml
select de.triggers_xml_data
from dbo.DEPLOYMENT_ENVIRONMENT as de
But this is not working and I tried to use this #filecontent.value('(//value)[1]','varchar(255)') and making it equal the column value, I have tried casting it but I can't find a way to do this. Is this possible?
When I do this:
SELECT
CAST(
REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '')
AS XML).value('(triggers/triggerDefinition/config/item/value)[1]', 'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819
I am getting a null value returned.
Here is an example of what my xml could look like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration xml:space="preserve">
<triggers>
<defined>true</defined>
<triggerDefinition>
<id>1</id>
<name>After successful deployment</name>
<userDescription/>
<isEnabled>true</isEnabled>
<pluginKey>com.atlassian.bamboo.triggers.atlassian-bamboo-triggers:afterSuccessfulDeployment</pluginKey>
<triggeringRepositories/>
<config>
<item>
<key>deployment.trigger.afterSuccessfulDeployment.triggeringEnvironmentId</key>
<value>19234819</value>
</item>
</config>
</triggerDefinition>
</triggers>
<bambooDelimiterParsingDisabled>true</bambooDelimiterParsingDisabled>
</configuration>
The XML, as you posted it, is not valid. Your code example does not work... It is not allowed to use a namespace prefix without a namespace declaration. Furthermore your example misses the closing Header-tag...
I corrected this...
DECLARE #yourTbl TABLE(ID INT, YourXML NTEXT);
INSERT INTO #yourTbl VALUES
(1,N'<my:Header xmlns:my="DummyUrl">
<my:Requestor>Mehrlein, Roswitha</my:Requestor>
<my:RequestorUserName>SJM\MehrlR01</my:RequestorUserName>
<my:RequestorEmail>RMehrlein#SJM.com</my:RequestorEmail>
<my:HRContact>Roswita Mehrlein, Beatrice Porta</my:HRContact>
<my:Entity>SJM Germany</my:Entity>
<my:Department>HR/Administration</my:Department>
<my:PositionTitle>Sales Representative</my:PositionTitle>
<my:JobDescription>x0lGQRQAAAABAAAAAAAAAAAeAQAyAAAAVgBAAAAA=</my:JobDescription>
<my:PositionDepartment>Sales</my:PositionDepartment>
</my:Header>');
--Lazy approach
SELECT ID
,CAST(CAST(YourXml AS NVARCHAR(MAX)) AS XML).value(N'(//*:PositionDepartment)[1]','nvarchar(max)')
FROM #yourTbl;
--explicit approach
WITH XMLNAMESPACES('DummyUrl' AS my)
SELECT ID
,CAST(CAST(YourXml AS NVARCHAR(MAX)) AS XML).value(N'(/my:Header/my:PositionDepartment)[1]','nvarchar(max)')
FROM #yourTbl
Some Background
If possible you should not store XML in other format than XML and further more one should avoid NTEXT, as it is depricated since SS2005!.
You have to cast NTEXT to NVARCHAR(MAX) first, than cast this to XML. The second will break, if the XML is not valid. That means: If the XML is really the way you posted it, this cannot work!
UPDATE: String-based approach, if XML does not work
If you cannot cast this to XML you might try this
--String based
WITH Casted AS
(
SELECT ID
,CAST(YourXML AS NVARCHAR(MAX)) AS TheXmlAsString
FROM #yourTbl
)
,WithPosition AS
(
SELECT Casted.*
,CHARINDEX(N'<my:PositionDepartment>',TheXmlAsString) + LEN(N'<my:PositionDepartment>') AS FirstLetter
FROM Casted
)
SELECT ID
,SUBSTRING(TheXmlAsString,FirstLetter,CHARINDEX('<',TheXmlAsString,FirstLetter)-FirstLetter)
FROM WithPosition
UPDATE 2
According to your edit the following returns a NULL value. This is good, because it shows, that the cast was successfull.
SELECT
CAST(
REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '')
AS XML).value('(triggers/triggerDefinition/config/item/value)[1]',
'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819
Try this (skip namespace with wildcard):
SELECT
CAST(
REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '')
AS XML).value('(*:triggers/*:triggerDefinition/*:config/*:item/*:value)[1]', 'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819
And this should be even better:
SELECT
CAST(CAST(de.TRIGGERS_XML_DATA AS NVARCHAR(MAX)) AS XML).value('(*:triggers/*:triggerDefinition/*:config/*:item/*:value)[1]', 'NVARCHAR(max)') as Item, de.ENVIRONMENT_ID
from dbo.DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819
UPDATE 3
I'd rather cut away the full declaration. Your posted example would go like this
DECLARE #DEPLOYMENT_ENVIRONMENT TABLE(ENVIRONMENT_ID INT, TRIGGERS_XML_DATA NTEXT);
INSERT INTO #DEPLOYMENT_ENVIRONMENT VALUES
(19234819,N'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration xml:space="preserve">
<triggers>
<defined>true</defined>
<triggerDefinition>
<id>1</id>
<name>After successful deployment</name>
<userDescription/>
<isEnabled>true</isEnabled>
<pluginKey>com.atlassian.bamboo.triggers.atlassian-bamboo-triggers:afterSuccessfulDeployment</pluginKey>
<triggeringRepositories/>
<config>
<item>
<key>deployment.trigger.afterSuccessfulDeployment.triggeringEnvironmentId</key>
<value>19234819</value>
</item>
</config>
</triggerDefinition>
</triggers>
<bambooDelimiterParsingDisabled>true</bambooDelimiterParsingDisabled>
</configuration>');
WITH Casted AS
(
SELECT CAST(de.TRIGGERS_XML_DATA AS NVARCHAR(MAX)) AS XmlAsSting
FROM #DEPLOYMENT_ENVIRONMENT as de
where de.ENVIRONMENT_ID = 19234819
)
SELECT CAST(SUBSTRING(XmlAsSting,CHARINDEX('?>',XmlAsSting)+2,8000) AS XML).value('(/*:configuration/*:triggers/*:triggerDefinition/*:config/*:item/*:value)[1]', 'NVARCHAR(max)') as Item
FROM Casted;

SQL Server column containing XML needs to be concatentated

I have a sql server 2008 r2 database that contains a table with raw XML in one of the columns. I have written a query to extract data from this table using group by and stuff to concatenate all of the columns that meet a 2 column group by clause. The issue is that when I stuff the columns I get duplicate XML declarations and the XML is not valid.
<?xml version="1.0" encoding="UTF-8"?>
<Fruits>
<Fruit Type="Lemons" Price="0.50" />
<Fruit Type="Apples" Price="0.75" />
</Fruits>
<?xml version="1.0" encoding="UTF-8"?>
<Fruits>
<Fruit Type="Cherries" Price="0.10" />
<Fruit Type="Dates" Price="0.25" />
</Fruits>
I looked at adding a substring call to remove this declaration but the query is getting quite complex and slow. I am working with an XSLT transformer that creates XML output. In the end I have many rows that can be delivered to a common destination. I basically need a way to concatenate the XML while removing the duplicate XML declarations and handling the XML hierarchy
This would be converted to
<?xml version="1.0" encoding="UTF-8"?>
<Fruits>
<Fruit Type="Lemons" Price="0.50" />
<Fruit Type="Apples" Price="0.75" />
<Fruit Type="Cherries" Price="0.10" />
<Fruit Type="Dates" Price="0.25" />
</Fruits>
Does anyone know how to do this in a systematic way? I am not actually working with fruit but used it as a simplified example.
Here is the actual query
SELECT tt.ProductCodeID, tt.ProviderID, tt.ContentXML, LEN(tt.ContentXML) AS xmllength from
(SELECT p.ProductCodeID, l.ProviderID,
STUFF((
SELECT pl1.Content FROM dbo.Payload pl1
INNER JOIN Log l1 ON pl1.LogID=l1.LogID
INNER JOIN Provider p1 ON l1.ProviderID=p1.ProviderID
WHERE pl1.ProductCodeID=p.ProductCodeID AND
pl1.PayloadTypeID=pt.PayloadTypeID
AND p1.ProviderID=l.ProviderID
FOR XML PATH(''), TYPE).value('.','varchar(max)'),1,1,'') AS ContentXML
FROM dbo.Queue q
INNER JOIN log l ON q.LogID=l.LogID
INNER JOIN payload pl ON l.LogID=pl.LogID
INNER JOIN dbo.PayloadType pt ON pl.PayloadTypeID = pt.PayloadTypeID
INNER JOIN dbo.ProductCode p ON pl.ProductCodeID= p.ProductCodeID
INNER JOIN dbo.Status s ON q.StatusID=s.StatusID
WHERE s.Name = 'processed' AND pt.Name='MIF'
GROUP BY p.ProductCodeID, l.ProviderID, pt.PayloadTypeID) AS tt
Thank you
It's ugly, but if you always know what the objects are going to be you could strip out the xml you don't want.
SELECT ..., '<?xml version="1.0" encoding="UTF-8"?><Fruits>' +
REPLACE( REPLACE(xml_column,
'<?xml version="1.0" encoding="UTF-8"?><Fruits>',
''),
'</Fruits',
'') +
'</Fruits>
Or, use a similar step to preprocess the data, and use the replace function to add a column missing the xml headers.
This one is the quick solution that I can think of right now.
CREATE TABLE Test2(ID INT,Col1 XML, Col2 XML)
INSERT INTO Test2 VALUES(1,'<?xml version="1.0" encoding="UTF-8"?><Fruits><Fruit Type="Lemons" Price="0.10" /><Fruit Type="Apples" Price="0.25" /></Fruits>','<?xml version="1.0" encoding="UTF-8"?><Fruits><Fruit Type="Cherries" Price="0.10" /><Fruit Type="Dates" Price="0.25" /></Fruits>')
INSERT INTO Test2 VALUES(2,'<?xml version="1.0" encoding="UTF-8"?><Fruits><Fruit Type="Lemons2" Price="0.10" /><Fruit Type="Apples2" Price="0.25" /></Fruits>','<?xml version="1.0" encoding="UTF-8"?><Fruits><Fruit Type="Cherries2" Price="0.10" /><Fruit Type="Dates3" Price="0.25" /></Fruits>')
SELECT ID, (
SELECT Fruit,Price FROM(
SELECT
Tbl.Col.value('#Type', 'varchar(100)') AS Fruit,
Tbl.Col.value('#Price', 'varchar(10)') AS Price
FROM Col1.nodes('//Fruit') Tbl(Col)
UNION
SELECT
Tbl.Col.value('#Type', 'varchar(100)'),
Tbl.Col.value('#Price', 'varchar(10)')
FROM Col2.nodes('//Fruit') Tbl(Col)) Fruits FOR XML AUTO
) FROM Test2

Parse an xml data column on a table in SQL Server 2012

How do I parse an xml column on a table of data in SQL Server 2012
Sample data
<GetOfferAvailabilityResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p3="http://somewebsite.com/v2.0" xmlns="http://somewebsite.com/v2.0" p3:TransactionID="281234567">
<p3:RuleResultList xsi:nil="true" />
<p3:ResultList>
<p3:ProviderResult p3:ProviderID="01" p3:ResultID="1234" p3:ResultType="NotAvailable" p3:ResultCode="NotAvailable" p3:BrokerID="55" p3:Structure="None">
<p3:EntityState>None</p3:EntityState>
<p3:ResultText>No Orders returned</p3:ResultText>
<p3:ShortDescription>Not Available</p3:ShortDescription>
<p3:LongDescription>We're sorry, but offers are currently not available for your service address.</p3:LongDescription>
<p3:ResultAction>ErrorMessage</p3:ResultAction>
<p3:SourceResultCode xsi:nil="true" />
</p3:ProviderResult>
</p3:ResultList>
</GetOfferAvailabilityResponse>'
I tried:
DECLARE #x xml
SET #x =
DECLARE #test TABLE (ID INT, XmlRule XML)
Insert into #test VALUES(1,'
<GetOfferAvailabilityResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" ---GetOfferAvailabilityResponse>')
When I use Select #test.query ('\') I get the entire xml but when I try Select #test.query ('\GetOfferAvailabilityResponse') I receive an empty result
You can try something like this:
DECLARE #XmlTbl TABLE (ID INT, XMLDATA XML)
INSERT INTO #XmlTbl
( ID, XMLDATA )
VALUES ( 1, '<GetOfferAvailabilityResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p3="http://somewebsite.com/v2.0" xmlns="http://somewebsite.com/v2.0" p3:TransactionID="281234567">
<p3:RuleResultList xsi:nil="true" />
<p3:ResultList>
<p3:ProviderResult p3:ProviderID="01" p3:ResultID="1234" p3:ResultType="NotAvailable" p3:ResultCode="NotAvailable" p3:BrokerID="55" p3:Structure="None">
<p3:EntityState>None</p3:EntityState>
<p3:ResultText>No Orders returned</p3:ResultText>
<p3:ShortDescription>Not Available</p3:ShortDescription>
<p3:LongDescription>We''re sorry, but offers are currently not available for your service address.</p3:LongDescription>
<p3:ResultAction>ErrorMessage</p3:ResultAction>
<p3:SourceResultCode xsi:nil="true" />
</p3:ProviderResult>
</p3:ResultList>
</GetOfferAvailabilityResponse>')
;WITH XMLNAMESPACES('http://somewebsite.com/v2.0' AS p3, DEFAULT 'http://somewebsite.com/v2.0')
SELECT
ProviderID = XmlData.value('(/GetOfferAvailabilityResponse/p3:ResultList/p3:ProviderResult/#p3:ProviderID)[1]', 'varchar(50)'),
EntityState = XmlData.value('(/GetOfferAvailabilityResponse/p3:ResultList/p3:ProviderResult/p3:EntityState)[1]', 'varchar(50)'),
ResultText = XmlData.value('(/GetOfferAvailabilityResponse/p3:ResultList/p3:ProviderResult/p3:ResultText)[1]', 'varchar(50)'),
ShortDescription = XmlData.value('(/GetOfferAvailabilityResponse/p3:ResultList/p3:ProviderResult/p3:ShortDescription)[1]', 'varchar(250)'),
LongDescription = XmlData.value('(/GetOfferAvailabilityResponse/p3:ResultList/p3:ProviderResult/p3:LongDescription)[1]', 'varchar(250)'),
ResultAction = XmlData.value('(/GetOfferAvailabilityResponse/p3:ResultList/p3:ProviderResult/p3:ResultAction)[1]', 'varchar(50)')
FROM
#XmlTbl
From a table that contains a column of type XML, select those bits and pieces that you need, taking into account the defined XML namespaces on your XML data
This gives me a result of:

SQL server XML type

I have an XML type column in SQL server:
<LogMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LogMessageBusinessServiceRequest">
<Application>Services.Business.myapp</Application>
<Time>2013-05-30T15:01:38.932Z</Time>
<Level>Info</Level>
<Message>MultiQuery Biz Request</Message>
<MachineName>Machine1</MachineName>
<ThreadId>16084</ThreadId>
<Callsite>BLAH</Callsite>
<CreatedBy>Machine1\svc_biz_myapp</CreatedBy>
<Context>
<myappExtraInfo xmlns="http://services.somedomain.com/myapp/logging/extraInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CallType>MultiProcessQuery</CallType>
<RequestId>r163505508498822282742</RequestId>
<FirmId>160</FirmId>
<PMFirmId>203</PMFirmId>
<SubscriptionId>0</SubscriptionId>
<Token />
<LastClientSvcTimeMs>0</LastClientSvcTimeMs>
<ResultCode>0</ResultCode>
<ResultCodeDescription>OK</ResultCodeDescription>
<ElapsedTimeTotalMs>110</ElapsedTimeTotalMs>
<ElapsedTimeMtMs>110</ElapsedTimeMtMs>
<ElapsedTimeDacMs>109</ElapsedTimeDacMs>
<ElapsedTimePMSSMs>-1</ElapsedTimePMSSMs>
</myappExtraInfo>
</Context>
I want to get the FirmID from there. But I am not able with the following section of my select statement:
select
[Body].value('(/LogMessage/Context/myappExtraInfo/FirmId)[1]', 'varchar(max)') FirmID
What am I doing wrong?
Thanks for your time.
Shiyam
Try this - you need to respect the XML namespace that's defined on your <myappExtraInfo> node (and thus applies to all subnodes, too):
DECLARE #Test TABLE (ID INT NOT NULL, XmlContent XML)
INSERT INTO #Test VALUES(1,
'<LogMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LogMessageBusinessServiceRequest">
<Application>Services.Business.myapp</Application>
<Time>2013-05-30T15:01:38.932Z</Time>
<Level>Info</Level>
<Message>MultiQuery Biz Request</Message>
<MachineName>Machine1</MachineName>
<ThreadId>16084</ThreadId>
<Callsite>BLAH</Callsite>
<CreatedBy>Machine1\svc_biz_myapp</CreatedBy>
<Context>
<myappExtraInfo xmlns="http://services.somedomain.com/myapp/logging/extraInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CallType>MultiProcessQuery</CallType>
<RequestId>r163505508498822282742</RequestId>
<FirmId>160</FirmId>
<PMFirmId>203</PMFirmId>
<SubscriptionId>0</SubscriptionId>
<Token />
<LastClientSvcTimeMs>0</LastClientSvcTimeMs>
<ResultCode>0</ResultCode>
<ResultCodeDescription>OK</ResultCodeDescription>
<ElapsedTimeTotalMs>110</ElapsedTimeTotalMs>
<ElapsedTimeMtMs>110</ElapsedTimeMtMs>
<ElapsedTimeDacMs>109</ElapsedTimeDacMs>
<ElapsedTimePMSSMs>-1</ElapsedTimePMSSMs>
</myappExtraInfo>
</Context>
</LogMessage>')
;WITH XMLNAMESPACES('http://services.somedomain.com/myapp/logging/extraInfo' AS ns)
SELECT
XmlContent.value('(/LogMessage/Context/ns:myappExtraInfo/ns:FirmId)[1]', 'int')
FROM #Test
WHERE ID = 1
This returns the value 160 to me.