I have a XML like below. In this i want to fetch 'Name' value. i.e AAA in SQL Server.
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:out="http://www.google.com">
<soapenv:Body>
<MER xmlns="http://www.google.com/services">
<ns1:RequestHeader xmlns:ns1="http://www.google.com//services">
<ns1:Info>
<ns1:Name>AAA</ns1:Name>
<ns1:TransactionId>Mdow0-NHPHuNu7eiEUxb</ns1:TransactionId>
<ns1:SubmitDateTime>2015-09-12T15:48:44.000Z</ns1:SubmitDateTime>
<ns1:SessionId>Mdow0-NHPHuNu7eiEUxb</ns1:SessionId>
<ns1:Timeout>60</ns1:Timeout>
<ns1:MaxRows>100</ns1:MaxRows>
<ns1:TransactionLog>
<ns1:Info1>1234567</ns1:Info1>
<ns1:Info2>ABC123</ns1:Info2>
</ns1:TransactionLog>
</ns1:Info>
<ns1:CorrelatedData>
<ns1:UserID>ABC123</ns1:UserID>
<ns1:UserRole>My Members</ns1:UserRole>
<ns1:TransactionName>Login</ns1:TransactionName>
<ns1:ClientSubmitDateTime>2010-09-12 11:48:44 PM</ns1:ClientSubmitDateTime>
</ns1:CorrelatedData>
</ns1:RequestHeader>
<SearchCriteria>
<MemberID>123456</MemberID>
</SearchCriteria>
</MER>
SqlFiddleDemo
DECLARE #x XML =
N'<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:out="http://www.google.com">
<soapenv:Body>
<MER xmlns="http://www.google.com/services">
<ns1:RequestHeader xmlns:ns1="http://www.google.com//services">
<ns1:Info>
<ns1:Name>AAA</ns1:Name>
<ns1:TransactionId>Mdow0-NHPHuNu7eiEUxb</ns1:TransactionId>
<ns1:SubmitDateTime>2015-09-12T15:48:44.000Z</ns1:SubmitDateTime>
<ns1:SessionId>Mdow0-NHPHuNu7eiEUxb</ns1:SessionId>
<ns1:Timeout>60</ns1:Timeout>
<ns1:MaxRows>100</ns1:MaxRows>
<ns1:TransactionLog>
<ns1:Info1>1234567</ns1:Info1>
<ns1:Info2>ABC123</ns1:Info2>
</ns1:TransactionLog>
</ns1:Info>
<ns1:CorrelatedData>
<ns1:UserID>ABC123</ns1:UserID>
<ns1:UserRole>My Members</ns1:UserRole>
<ns1:TransactionName>Login</ns1:TransactionName>
<ns1:ClientSubmitDateTime>2010-09-12 11:48:44 PM</ns1:ClientSubmitDateTime>
</ns1:CorrelatedData>
</ns1:RequestHeader>
<SearchCriteria>
<MemberID>123456</MemberID>
</SearchCriteria>
</MER>
</soapenv:Body>
</soapenv:Envelope>';
WITH XMLNAMESPACES(
'http://www.google.com//services' AS ns1
)
SELECT
t.c.value('ns1:Name[1]', 'NVARCHAR(100)') AS name
FROM #x.nodes('//ns1:Info') as t(c);
We can read xml data in SQL Server as below:
DECLARE #xml XML =
'<DataTable>
<Employee>
<ID>100</ID>
<Name>Rohan</Name>
<Age>30</Age>
<Gender>Male</Gender>
<City>Delhi</City>
<State>Delhi</State>
</Employee>
</DataTable>'
SELECT
tbl.col.value('ID[1]', 'smallint') AS ID,
Tbl.Col.value('Name[1]', 'varchar(100)') AS Name,
Tbl.Col.value('Age[1]', 'smallint') AS Age,
Tbl.Col.value('Gender[1]', 'varchar(10)') AS Gender,
Tbl.Col.value('City[1]', 'varchar(50)') AS City,
Tbl.Col.value('State[1]', 'varchar(50)') AS State
FROM #xml.nodes('/DataTable/Employee') tbl(col)
To read more on how to read xml data visit below link
Read xml data as table in SQL Server
In case you want to read xml nodes dynamically with unknown number of elements, visit this link:
Read xml nodes dynamically in SQL Server
Related
I'm using SSIS\SQL Server 2014 and am using the below SQL statement to output to XML.
In summary, 1 property can have many schedules. I only want the name space to appear once before the 'Job' XML path, however, if there are multiple schedules, then the namespace is also appearing in the xml output for each schedule - how do I stop this?
My code:
DECLARE #XMLOutput XML
DECLARE #XMLOutputChar nvarchar(max)
;WITH XMLNAMESPACES('http://www.example.com' as ns)
SELECT #XMLOutput =
(
SELECT
ISNULL(T1.[PropertyID],'') as PropertyId,
ISNULL(T1.[Desc],'') as JobDescription,
(
SELECT
ScheduleId as ScheduleId,
LocationID as LocationId,
FROM [JobSchedules]
WHERE T1.JobIdentity = JobIdentity
FOR XML PATH('JobSchedules'), TYPE
)
FROM [JobFile] T1
FOR XML PATH('Job'),TYPE,ROOT('JobLoader')
)
SET #XMLOutputChar = '<?xml version="1.0" encoding="UTF-8"?>' + CONVERT(nvarchar(max),#XMLOutput)
SELECT #XMLOutputChar AS XMLOutput
This is the desired output:
<?xml version="1.0" encoding="utf-8"?>
<JobLoader xmlns="http://www.example.com/" >
<Job>
<PropertyId>PROPERTYID</PropertyId>
<JobDescription>JOBDESCRIPTION</JobDescription>
<JobSchedules>
<JobSchedule>
<ScheduleId>SCHEDULEID</ScheduleId>
<LocationId>LOCATIONID</LocationId>
</JobSchedule>
</JobSchedules>
</Job>
</JobLoader>
What am I missing?
If anyone is interested I was able to resolve this by adding the below line to replace the value just after the encoding line:
SET #XMLOutputChar = REPLACE(#XMLOutputChar,'<JobSchedules xmlns:ns="http://www.example.com/"','<JobSchedules ')
If I have this XML
<TradingInquirySearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchTerm>test</SearchTerm>
<CompanyFound>true</CompanyFound>
<CompanyInfoCollection>
<CompanyInfo>
<CompanyID>26</CompanyID>
<CompanyName>test</CompanyName>
<Status>Unrestricted</Status>
<SearchTags>
<Tag>test2</Tag>
<Tag>test3</Tag>
<Tag>test4</Tag>
</SearchTags>
</CompanyInfo>
</CompanyInfoCollection>
</TradingInquirySearchResult>
I want to get "test2;test3;test4". How can I join the values of <Tag> for the first <CompanyInfo> tag?
I tried TransactionData.value('(/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo[1]/SearchTags/Tag)[1]', 'nvarchar(1000)')
but it didn't work.
Thanks
As you're using SQL Server 2012 (or rather not 2017+) the common way to aggregate strings is to use FOR XML PATH and STUFF, and you can get the multiple values for the node Tag using the nodes operator. This gives you the below:
DECLARE #XML xml = '
<TradingInquirySearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchTerm>test</SearchTerm>
<CompanyFound>true</CompanyFound>
<CompanyInfoCollection>
<CompanyInfo>
<CompanyID>26</CompanyID>
<CompanyName>test</CompanyName>
<Status>Unrestricted</Status>
<SearchTags>
<Tag>test2</Tag>
<Tag>test3</Tag>
<Tag>test4</Tag>
</SearchTags>
</CompanyInfo>
</CompanyInfoCollection>
</TradingInquirySearchResult>';
SELECT STUFF((SELECT N';' + ST.Tag.value('(./text())[1]','nvarchar(100)')
FROM (VALUES(#XML))V(X)
CROSS APPLY V.X.nodes('/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo/SearchTags/Tag') ST(Tag)
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') AS Tags
Edit for guess when multiple companies.
If you only want the first company, then yes, using [1] would work:
DECLARE #XML xml = '
<TradingInquirySearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchTerm>test</SearchTerm>
<CompanyFound>true</CompanyFound>
<CompanyInfoCollection>
<CompanyInfo>
<CompanyID>26</CompanyID>
<CompanyName>test</CompanyName>
<Status>Unrestricted</Status>
<SearchTags>
<Tag>test2</Tag>
<Tag>test3</Tag>
<Tag>test4</Tag>
</SearchTags>
</CompanyInfo>
<CompanyInfo>
<CompanyID>27</CompanyID>
<CompanyName>Sample</CompanyName>
<Status>Restricted</Status>
<SearchTags>
<Tag>test6</Tag>
<Tag>test7</Tag>
<Tag>test8</Tag>
</SearchTags>
</CompanyInfo>
</CompanyInfoCollection>
</TradingInquirySearchResult>';
SELECT STUFF((SELECT N';' + ST.Tag.value('(./text())[1]','nvarchar(100)')
FROM (VALUES(#XML))V(X)
CROSS APPLY V.X.nodes('/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo[1]/SearchTags/Tag') ST(Tag)
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') AS Tags;
If, however, you want a row per company, then you would want to do something like this:
SELECT CIC.CI.value('(./CompanyID/text())[1]','nvarchar(50)') AS CompanyID,
STUFF((SELECT N';' + ST.Tag.value('(./text())[1]','nvarchar(100)')
FROM CIC.CI.nodes('./SearchTags/Tag') ST(Tag)
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') AS Tags
FROM (VALUES(#XML))V(X)
CROSS APPLY V.X.nodes('/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo') CIC(CI);
I have this structure in my sql server :
<?xml version="1.0" encoding="utf-16"?>
<HydroResultTestParameterView xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReceptionId>11</ReceptionId>
<CapsuleCompany>BR</CapsuleCompany>
<CapsuleSerialNumber>228154</CapsuleSerialNumber>
<CapsuleType>1</CapsuleType>
<CapsuleBuiltDate>1389</CapsuleBuiltDate>
<CapsuleExpireDate>1405</CapsuleExpireDate>
<GasSystemGeneration>1</GasSystemGeneration>
<Remark>ok</Remark>
</HydroResultTestParameterView>
My datatype of my column in nvarchar(max).So i want to get all of ReceptionId result that has CapsuleCompany=BR .How can i find these result ?
This explicitely selects all nodes using a XPath expression, taking all HydroResultTestParameterView with a sub-element CapsuleCompany with text = "BR": /HydroResultTestParameterView[CapsuleCompany="BR"]/ReceptionId
DECLARE #t TABLE(x XML);
INSERT INTO #t(x)VALUES(N'<HydroResultTestParameterView xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReceptionId>11</ReceptionId>
<CapsuleCompany>BR</CapsuleCompany>
<CapsuleSerialNumber>228154</CapsuleSerialNumber>
<CapsuleType>1</CapsuleType>
<CapsuleBuiltDate>1389</CapsuleBuiltDate>
<CapsuleExpireDate>1405</CapsuleExpireDate>
<GasSystemGeneration>1</GasSystemGeneration>
<Remark>ok</Remark>
</HydroResultTestParameterView>');
SELECT
n.v.value('.[1]','NVARCHAR(MAX)')
FROM
#t
CROSS APPLY x.nodes('/HydroResultTestParameterView[CapsuleCompany="BR"]/ReceptionId') AS n(v)
SELECT
convert(xml,ResultTest).query('/HydroResultTestParameterView/CapsuleSerialNumber')
FROM
[S].[dbo].[HydrostaticTests]
WHERE
convert(xml,ResultTest).exist('/HydroResultTestParameterView[CapsuleSerialNumber="47274"]') = 1;
//-----------------
SELECT
convert(xml,ResultTest).value('(/HydroResultTestParameterView/CapsuleSerialNumber)[1]', 'int')
FROM
[S].[dbo].[HydrostaticTests]
WHERE
convert(xml,ResultTest).exist('/HydroResultTestParameterView[CapsuleSerialNumber="47274"]') = 1;
I have xml statement for which I want value for AlertString in table format:
<ArrayOfAlertInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AlertInfo>
<AlertString xmlns="http://www.example.org/abc/v1_0">Test 1</AlertString>
<AlertString xmlns="http://www.example.org/abc/v1_0">Test 2</AlertString>
<AlertString xmlns="http://www.example.org/abc/v1_0">Test 3</AlertString>
<AlertTime xmlns="http://www.example.org/abc/v1_0">1466227822997</AlertTime>
</AlertInfo>
</ArrayOfAlertInfo>
Desired result wanted:
Test 1 . Test 2 . Test 3
Try this :
DECLARE #input XML = '<ArrayOfAlertInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AlertInfo>
<AlertString xmlns="http://www.example.org/abc/v1_0">Test 1</AlertString>
<AlertString xmlns="http://www.example.org/abc/v1_0">Test 2</AlertString>
<AlertString xmlns="http://www.example.org/abc/v1_0">Test 3</AlertString>
<AlertTime xmlns="http://www.example.org/abc/v1_0">1466227822997</AlertTime>
</AlertInfo>
</ArrayOfAlertInfo>'
;WITH XMLNAMESPACES('http://www.example.org/abc/v1_0' AS ns)
SELECT
XC.value('(text())[1]', 'varchar(100)')
FROM
#input.nodes('/ArrayOfAlertInfo/AlertInfo/ns:AlertString') AS XT(XC)
Gives me an output of:
This artical can help you.
Reading XML File Using T-SQL
What am I not getting here? I can't get any return except NULL...
DECLARE #xml xml
SELECT #xml = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<webregdataResponse>
<result>0</result>
<regData />
<errorFlag>99</errorFlag>
<errorResult>Not Processed</errorResult>
</webregdataResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>'
DECLARE #nodeVal int
SELECT #nodeVal = #xml.value('(errorFlag)[1]', 'int')
SELECT #nodeVal
Here is the solution:
DECLARE #xml xml
SELECT #xml = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<webregdataResponse>
<result>0</result>
<regData />
<errorFlag>99</errorFlag>
<errorResult>Not Processed</errorResult>
</webregdataResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>'
declare #table table (data xml);
insert into #table values (#xml);
WITH xmlnamespaces (
'http://schemas.xmlsoap.org/soap/envelope/' as [soap])
SELECT Data.value('(/soap:Envelope/soap:Body/webregdataResponse/errorFlag)[1]','int') AS ErrorFlag
FROM #Table ;
Running the above SQL will return 99.
Snapshot of the result is given below,
That's because errorFlag is not the root element of your XML document. You can either specify full path from root element to errorFlag, for example* :
SELECT #nodeVal = #xml.value('(/*/*/*/errorFlag)[1]', 'int')
or you can use descendant-or-self axis (//) to get element by name regardless of it's location in the XML document, for example :
SELECT #nodeVal = #xml.value('(//errorFlag)[1]', 'int')
*: I'm using * instead of actual element name just to simplify the expression. You can also use actual element names along with the namespaces, like demonstrated in the other answer.