SQL query to retrive value from XMl xolumn - sql-server

I have a column in table with datatype XML.
mycolumn has following value
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www
.w3.org/2001/XMLSchema"
xmlns:ns1="http://http://localhost/test/">
<SOAP-ENV:Body>
<ns1:IDResults>
<NCNL>
<Value>123</Value>
</NCNL>
</ns1:IDResults>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
select mycolumn.query('./Envelope/Body')
My above select statement does not return anything.
Do I need to specify SOAP-ENV: prefix, if yes than how do I specify it?
Thanks in advance.

The actual query depends on what you want to get, but basically you have to specify namespace in your query, like this:
;with xmlnamespaces ('http://schemas.xmlsoap.org/soap/envelope/' as [SOAP-ENV])
select #data.query('SOAP-ENV:Envelope/SOAP-ENV:Body/*')

Related

how to access value of XML

SQL Server 2012
How to access "datefrom" value from below XML? Have try almost everything but without success :(
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope">
<SOAP-ENV:Body>
<ns0:getInterestAndExchangeRatesResponse xmlns:ns0="http://swea.riksbank.se/xsd">
<return>
<datefrom>2020-03-05</datefrom>
<dateto>2020-03-05</dateto>
</return>
</ns0:getInterestAndExchangeRatesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
You need to respect the XML namespaces in play - but once you do, this should work for you:
DECLARE #Data XML = '....(your XML here).....';
-- define the two XML namespaces in play
WITH XMLNAMESPACES('http://www.w3.org/2003/05/soap-envelope' AS soap,
'http://swea.riksbank.se/xsd'AS ns)
SELECT
#Data.value('(soap:Envelope/soap:Body/ns:getInterestAndExchangeRatesResponse/return/datefrom)[1]', 'varchar(20)')
This will return something like:
2020-03-05

Trying to query XML Data - node has a space in it

I am trying to learn how to work with xml files and data in SQL Server and I'm trying to query an xml file but nothing is returned.
Here is the xml data:
<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="AdmissionsByPCP" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="AdmissionsByPCP" xsi:schemaLocation="AdmissionsByPCP http://10.xxx.x.xx/ReportServer_NameofReportServer?%2FHl%20C%20Syst%20Reports%2health%2FAdmissBy&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID=h0iz5ijxgt2vdl45g3pjfs45&rc%3ASchema=True">
<Tablix2>
<Details_Collection>
<Details PCPCarrier="DoctorsName">
<Subreport1>
<Report Name="PCPAdmitSubReport">
<Tablix5 Textbox5="79">
<Details_Collection>
<Details Textbox37="Discharge Dx Code: ICDCode" Textbox89="Admit Dx Code: ICDCode" LOS="4" DischargeDate="07/10/2017" AdmitDate="07/06/2017" Hospital="Hospital Name" MemberName="Name" DOB="1/1/2019" AdmissionType="Inpatient" MemberNo="12345" Auth="321*I" Status="Close" AdmissionID="00001" LobName="Medicare" CarrierName="CarrierName"/>
</Details></Details_Collection></Tablix5></Report></Subreport1></Details></Details_Collection></Tablix2></Report>
Here is the query I'm using:
Declare #XMLData as XML
Set #XMLData=(
Select bulkcolumn
FROM OPENROWSET (Bulk '\Directory\AdmissionsByPCP.xml',
Single_Blob) a)
Select
#XMLData.value('(/Root/Report/Tablix2/Detail_Collections/DetailsPCPCarrier) [1]', 'varchar(max)') PCP
The query returns null and I don't know why. Is it because there is a space in the node (<Details PCPCarrier>) and if so how do I work around that?
You have misunderstood how XML works. This is the node you are looking for:
<Details PCPCarrier="DoctorsName">
This is not a node called Details PCPCarrier; it is a node called Details with an attribute called PCPCarrier.
So the XPath to select it would be:
/Root/Report/Tablix2/Detail_Collections/Details
Or, if you want to specifically filter by the PCPCarrier attribute existing:
/Root/Report/Tablix2/Detail_Collections/Details[#PCPCarrier]
Or, to get the value of the attribute itself:
/Root/Report/Tablix2/Detail_Collections/Details/#PCPCarrier
IMSoP pointed me in the right direction and I figured out the rest myself.
I also needed to add this:
With XMLNAMESPACES (Default 'AdmissionsByPCP')
So the query looks like this:
Declare #XMLData as XML
Set #XMLData=(
Select *
FROM OPENROWSET (Bulk '\\Directory\AdmissionsByPCP.xml',
Single_Clob) a );
With XMLNAMESPACES (Default 'AdmissionsByPCP')
Select
#XMLData.value('(/Report/Tablix2/Details_Collection/Details/#PCPCarrier)
[1]', 'varchar(max)')

Retrieve an element value from an XML string during an SQL select request

I'm querying a table T which has a string column StrXML that has XML text stored in it. Here's an example of the XML stored:
<Sequence mc:Ignorable="sap sads" DisplayName="Post Processing"
sap:VirtualizedContainerService.HintSize="424,318"
mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"
xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006
xmlns:mee="clr-namespace:MatX.eRP.Entities;assembly=eRP.Entities"
xmlns:mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities"
xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"
xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mepa:BasicOperation Description="Traitement Thermique" DisplayName="HeatTreatment" Guid="82800b59-e181-4a93-b483-7e2cd9b14827" sap:VirtualizedContainerService.HintSize="402,154" Scope="Build">
<mepa:BasicOperation.MeasurementDescriptions>
<scg:List x:TypeArguments="mee:MeasurementDescription" Capacity="0" />
</mepa:BasicOperation.MeasurementDescriptions>
</mepa:BasicOperation>
<mepa:BasicOperation Description="Finition manuelle" DisplayName="Manual Finishing" Guid="cd64be75-6968-47fe-8aac-93a4fdf37892">
<mepa:BasicOperation.MeasurementDescriptions>
<scg:List x:TypeArguments="mee:MeasurementDescription" Capacity="4">
<mee:MeasurementDescription Max="{x:Null}" Min="{x:Null}" Guid="7c1a37f1-f39d-4ed3-8048-6b0a266c70b9" IsRequired="False" Name="MesureMF1" Type="Double" />
<mee:MeasurementDescription Max="{x:Null}" Min="{x:Null}" Guid="a21b0c0d-dfff-4237-9975-4179bcefe7c2" IsRequired="False" Name="MesureMF2" Type="Double" />
</scg:List>
</mepa:BasicOperation.MeasurementDescriptions>
</mepa:BasicOperation>
</Sequence>
In my select request on table T, I want to only show the Description value for which the Guid="82800b59-e181-4a93-b483-7e2cd9b14827".
How can I do that?
In a comment I mentioned already, that one of your namespaces is missing the final ". This is a big problem, if it's not just a copy-and-paste issue... (not well formed)
XML should not be stored in a string column (slow and dangerous!). If you database does not support XML natively the XML should at least be checked.
You did not mention the actual RDBMS, but the XQuery-principles should be the same (however your RDBMS deals with XQuery actually).
The simple approach is this XQuery (fetch any <BasicOperation>, wherever it is placed, and filter for the given GUID)
//*:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description
With SQL-Server you can try this
SELECT CAST(T.StrXML AS XML).value(N'(//*:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description)[1]',N'nvarchar(max)')
The more specific (and recommended) approach is this:
declare namespace dflt="http://schemas.microsoft.com/netfx/2009/xaml/activities";
declare namespace mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities";
dflt:Sequence/mepa:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description
Again - with SQL-Server - you might try this:
SELECT CAST(T.StrXML AS XML).value(N'declare namespace dflt="http://schemas.microsoft.com/netfx/2009/xaml/activities";
declare namespace mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities";
(dflt:Sequence/mepa:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description)[1]',N'nvarchar(max)')
If the GUID-value is variable SQL-Server would allow you to pass the value in from a variable declared outside. Read about sql:variable() and sql:column().
UPDATE
You can use lower-case() to get a secure comparison:
DECLARE #xml XML=
'<root>
<a guid="82800b59-e181-4a93-b483-7e2cd9b14827" />
<a guid="82800B59-E181-4A93-B483-7E2CD9B14827" />
</root>';
DECLARE #guid UNIQUEIDENTIFIER='82800B59-E181-4A93-B483-7E2CD9B14827';
SELECT #xml.query(N'/root/a[lower-case(#guid)=lower-case(sql:variable("#guid"))]')
Try something like this, assuming this is for SQL Server:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/netfx/2009/xaml/activities',
'clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities' AS mepa)
SELECT
T.X.value('#Description', 'varchar(100)') AS JobTitle
FROM
#XTable
CROSS APPLY
XmlData.nodes('/Sequence/mepa:BasicOperation') AS T(X)
WHERE
T.X.value('#Guid','varchar(50)') = '82800b59-e181-4a93-b483-7e2cd9b14827'

SQL query xml data from varchar(max) column

I have a table called Content which has a varchar(max) column called data.
The data in this column is in XML format, and I want to query an attribute in the XML.
Below is the top couple of lines of the XML, it is the p3:manifestId I want to query so my output would basically be Some_Data (I've obviously desensitized this).
Is this possible?
<manifest xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p3="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.w3.org/2001/XMLSchema-instance"
p3:manifestDateTime="2016-02-17T17:34:29.5925096Z"
p3:manifestVersion="1.1" p3:manifestId="Some_Data">
<p3:productList>
<p3:product p3:releaseDateTime="2016-02-17T17:34:29.5925096Z" p3:installSeqId="2" p3:uninstallSeqId="2" p3:releaseNum="1" p3:productType="doc" p3:productId="WEDREZ020RRRP0GGG001" p3:mfgCode="GIRE">
The only thing which might be complicated here, are the namespaces. How is this XML generated? It is quite unusual to see the same namespace (http://www.w3.org/2001/XMLSchema-instance) as default and with two different aliases...
DECLARE #mockup TABLE(ID INT IDENTITY, YourXML VARCHAR(MAX));
INSERT INTO #mockup VALUES
('<manifest xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p3="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.w3.org/2001/XMLSchema-instance"
p3:manifestDateTime="2016-02-17T17:34:29.5925096Z"
p3:manifestVersion="1.1" p3:manifestId="Some_Data">
<!--Some more stuff-->
</manifest>');
--This approach does not look at namespaces at all. I use the wildcard *:
SELECT CAST(YourXML AS XML).value(N'(/*:manifest/#*:manifestId)[1]',N'nvarchar(max)')
FROM #mockup;
--This approach declares all needed namespaces in advance (best approach in most cases):
WITH XMLNAMESPACES(DEFAULT 'http://www.w3.org/2001/XMLSchema-instance'
,'http://www.w3.org/2001/XMLSchema-instance' AS p3)
SELECT CAST(YourXML AS XML).value(N'(/manifest/#p3:manifestId)[1]',N'nvarchar(max)')
FROM #mockup;
--This approach is usefull, if you really do not need more than one value. I use one alias ns1 for all different occurances of this namespace:
SELECT CAST(YourXML AS XML).value(N'declare namespace ns1="http://www.w3.org/2001/XMLSchema-instance";
(/ns1:manifest/#ns1:manifestId)[1]',N'nvarchar(max)')
FROM #mockup;

How to get data from XML Column that contain xml namespace (SQL Server 2005)

I google a lot and got no luck.
I can't retrieve data from XML column which data came from web service using sp_OAGetProperty.
the XML Column contain..
<ArrayOfCustomerInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Customer CustCode="001">
<CustName>John</CustName>
<Queues>
<Q>
<No>10</No>
<Line>1</Line>
</Q>
</Queues>
</Customer>
</ArrayOfCustomerInfo>
I got NULL when I execute following statement
(but works fine if I remove all XML namespace xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/")
SELECT a.b.value('#CustCode','varchar(4)') AS Code
,a.b.value('CustName[1]','varchar(20)') AS Name
,c.d.value('No[1]','int') AS QNo
,c.d.value('(Line)[1]','int') AS QLine
FROM PGHRMS_Employees x
CROSS APPLY x.data.nodes('/ArrayOfCustomerInfo/Customer') AS a(b)
CROSS APPLY a.b.nodes('Queues/Q') AS c(d)
please give me some advice. I've to achieve with SQL SERVER :(
If anyone want to reproduce it, I pasted script at : http://pastebin.com/ueZGidyL
Thank you in advance !!!
Try this:
;WITH XMLNAMESPACES(DEFAULT 'http://tempuri.org/')
SELECT
Code = XC1.value('#CustCode', 'varchar(4)'),
Name = XC1.value('CustName[1]', 'varchar(20)'),
QNo = XC2.value('No[1]', 'int') ,
QLine = XC2.value('(Line)[1]','int')
FROM
PGHRMS_Employees
CROSS APPLY
XmlContent.nodes('/ArrayOfCustomerInfo/Customer') AS XT1(XC1)
CROSS APPLY
XC1.nodes('Queues/Q') AS XT2(XC2)
With the WITH XMLNAMESPACES construct, you can define some XML namespaces to be used by the following T-SQL statement - default or prefixed namespaces alike.

Resources