XML sql query , attribute as column - sql

I need to query xml data available in server
<root>
<Parameter>
<Param>APP_REG_NUMBER</Param>
<Value>AL/T/2010/86</Value>
</Parameter>
<Parameter>
<Param>SUBLINEID</Param>
<Value>235931</Value>
</Parameter>
</root>
This is the structure I am saving data into SQL Server, I need output as follows:
Filed1 , Filed2 , APP_REG_NUMBER, SUBLINEID
something something , AL/T/2010/86, 235931
please do the needful

You can use XQuery for this, but realize you are recreating key-value-pairs in XML, which negates the ability to use schemas or XQuery/XPATH in any reasonable manner. Consider changing the format to:
<root>
<APP_REG_NUMBER>AL/T/2010/86</APP_REG_NUMBER>
<SUBLINEID>235931</SUBLINEID>
</root>
I digress... the query you want is:
DECLARE #testXml xml = N'<root>
<Parameter><Param>APP_REG_NUMBER</Param><Value>AL/T/2010/86</Value></Parameter>
<Parameter><Param>SUBLINEID</Param><Value>235931</Value></Parameter>
</root>'
SELECT
#testXml.value('(//Parameter[Param/text()="APP_REG_NUMBER"]/Value)[1]', 'nvarchar(50)') as APP_REG_NUMBER,
#testXml.value('(//Parameter[Param/text()="SUBLINEID"]/Value)[1]', 'nvarchar(50)') as SUBLINEID
You use the //Parameter syntax to find all Parameter elements and then filter them ([Param/text()="foobar"]) to only those which have a child named Value that have the inner text of SUBLINEID. From there, you navigate to the /Value child element and return the first result ((query)[1]).

Related

SQL query for XML data

I have a SQL Server database table with a column called XML that contains XML data which is structured like this:
<Item xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://test/data">
<Roots>
<Root>
<Name>Field Name</Name>
<Value>Field Value</Value>
</Root>
<Root>
<Name>Field Name</Name>
<Value>Field Value</Value>
</Root>
</Roots>
I want to use T-SQL to get the Value where Name = Total. I have tried the following but it isn't returning any data:
SELECT [XML]
FROM [BusinessAccount]
WHERE [XML].value('(/Root/Name)[13]', 'VARCHAR(MAX)') LIKE '%Total%'
If anyone could tell me where I've gone wrong?
You are missing the required WITH XMLNAMESPACES for your XML and the path is incorrect.
If you want to bring back rows where the 13th element consists of the text Total you can use the below.
WITH XMLNAMESPACES (DEFAULT 'http://test/data')
SELECT [XML]
FROM [BusinessAccount]
WHERE 1 = [XML].exist('(/Item/Roots/Root/Name)[13][text() = "Total"]')
Otherwise you can add the WITH XMLNAMESPACES to your original query and fix the path there too.
You need to specify namespaces. You can then match <Name> and <Value> pairs and extract the contents of <Value> like so:
SELECT NameNode.value('declare namespace x="http://test/data"; (../x:Value)[1]', 'varchar(100)')
FROM [BusinessAccount]
CROSS APPLY [XML].nodes('declare namespace x="http://test/data"; //x:Root/x:Name') AS n(NameNode)
WHERE NameNode.value('.', 'varchar(100)') = 'Total'
Demo on db<>fiddle

Query xml using xquery in SQL Server 2016

I have my XML in following format:
<resultset xmlns="qm_system_resultset" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<result>
<result_id>F5</result_id>
<exception>NO</exception>
<recurring_count>0</recurring_count>
<defect>NO</defect>
<unresolved>NO</unresolved>
<exception_approval />
<comments />
<exception_expiration>3000-01-01</exception_expiration>
<exception_stat_only>NO</exception_stat_only>
<result_data>
<phraseprefix>rx</phraseprefix>
<phrasenumber>0001</phrasenumber>
<languagedesc>Khmer</languagedesc>
<englishphrase> each time.</englishphrase>
<phrasedesc> គ្រាប់ក្នុងមួយដង។</phrasedesc>
<qm_translatedphrase>day.</qm_translatedphrase>
</result_data>
</result>
<result>
<result_id>26</result_id>
<exception>NO</exception>
<recurring_count>0</recurring_count>
<defect>NO</defect>
<unresolved>NO</unresolved>
<exception_approval />
<comments />
<exception_expiration>3000-01-01</exception_expiration>
<exception_stat_only>NO</exception_stat_only>
<result_data>
<phraseprefix>hold</phraseprefix>
<phrasenumber>0001</phrasenumber>
<languagedesc>Hmong</languagedesc>
<englishphrase>Hold than 160.</englishphrase>
<phrasedesc>Tsis 160.</phrasedesc>
<qm_translatedphrase>Do not use </qm_translatedphrase>
</result_data>
</result>
Using TSQL/XML query how do I achieve this RESULT
[phraseprefix][phrasenumber]
rx 0001
hold 0001
...
I tried the following query, but I got null values for both the columns:
DECLARE #input XML = (SELECT result_xml
FROM QM_Data_Audit.QM_Package.test_results
WHERE result_id = 2446338)
SELECT
resultset.value('(phraseprefix)[1]', 'varchar(max)') AS 'phrasenumber',
resultset.value('(phrasenumber)[1]', 'int') AS 'phrasenumber'
FROM #input.nodes('/resultset/result/result_data') AS List(resultset)
My apologies if the question is asked previously, I am new to querying XML.
Appreciate your help.
Your xml has a namespace declared so you need to provide this when querying it. In this example this can be acheived with the WITH XMLNAMESPACES statement:
DECLARE #input XML = (SELECT result_xml
FROM QM_Data_Audit.QM_Package.test_results
WHERE result_id = 2446338);
WITH XMLNAMESPACES(DEFAULT 'qm_system_resultset')
SELECT
resultset.value('(phraseprefix)[1]', 'varchar(max)') AS 'phrasenumber',
resultset.value('(phrasenumber)[1]', 'varchar(max)') AS 'phrasenumber'
FROM #input.nodes('/resultset/result/result_data') AS List(resultset)
You'll want to set the data type for phrasenumber to varchar as well to preserve the leading 0s if you need them.

Creating xml for SQL Server stored procedure

I have a function to insert an item into the database. It takes a lot of values as input and the values are passed as XML.
Consider a sample item XML:
<ROOT>
<Item
ItemName="CarlsApplication"
ItemTypeID="2">
<TSDefaultDescription DefaultitemDescription="C:\t.text"/>
<ItemSellers>
<ComputerObject Alias="" DisplayName="" ServiceName="" UserAccount="" />
<ComputerObject Alias="" DisplayName="" ServiceName="" UserAccount="" />
</ItemSellers>
<ItemOwners>
<ItemOwner Alias="rafchen" FirstName="Rafael" LastName="Chenkov"/>
</ItemOwners>
</Item>
</ROOT>
This has to be passed to stored procedure.
Now, each of these individual values in this XML, I have to extract from somewhere else. I can get the individual values like Item name etc, but how do I organize them into an XML that can be passed?
How do I construct this XML from the values I have?
I guess I will have to make some sort of template with this format and then put variables in that template and fill the variables to prepare the template.
Any help is greatly appreciated.
If I understand what you really want, You can use a query like this to generate that XML:
select
ItemName 'Item/#ItemName', --> Node:`Item` Attribute: `ItemName`
ItemTypeId 'Item/#ItemTypeId',
cast((
select
Alias 'ComputerObject/#Alias',
DisplayName 'ComputerObject/#DisplayName',
ServiceName 'ComputerObject/#ServiceName',
UserAccount 'ComputerObject/#UserAccount'
from
ItemSellers
where
ItemSellers.ItemId = Item.ItemId
for xml path('')) as xml) 'Item/ItemSellers', --> Node:`Item` Sub-Node:`ItemSellers`
cast((
select
Alias 'ItemOwner/#Alias',
FirstName 'ItemOwner/#FirstName',
LastName 'ItemOwner/#LastName'
from
ItemOwners
where
ItemOwners.ItemId = Item.ItemId
for xml path('')) as xml) 'Item/ItemOwners'
from
Item
for xml path('ROOT');
SQL Fiddle Demo

sql to extraction xml form column

This is the sample of xml in my table column;
Table name t005, column name ACTIVITYDETAIL, data type xml.
Sample of xml
<root>
<Parameter>
<Param>SearcgBy</Param>
<Value>ALL</Value>
</Parameter>
<Parameter>
<Param>SearchText</Param>
<Value>SA</Value>
</Parameter>
</root>
Now I want output as
Param value
SearchBy ALL
SearchText SA
I tried so many ways and here is my last try.
SELECT
p.value('(./Parameter/node())[1]', 'VARCHAR(8000)') as firstName,
p.value('(./Parameter/node())[2]', 'VARCHAR(8000)') as lastName
FROM
t005
CROSS APPLY
ACTIVITYDETAIL.nodes('/root') t(p)
Please help me.
Try this
SELECT
t.p.value('Param[1]','varchar(20)') as Param,
t.p.value('Value[1]','varchar(20)') as Value
FROM T005 CROSS APPLY ACTIVITYDETAIL.nodes('/root/Parameter') t(p)

How to add attributes to xml nodes in sql server 2005

If i wanted to add an attribute to the root element record, can i do this from the sql side?
SELECT top 1 'text' as nodeA
from test as z
FOR XML AUTO, ELEMENTS, root('record')
i would like to produce the xml like this:
<Root attribute="value">
<z>
<NodeA>text</NodeA>
</z>
</Root>
Use the new FOR XML PATH syntax:
SELECT TOP 1
'someValue' AS '#Attribute',
'text' as 'z/NodeA'
FROM dbo.Test
WHERE....
FOR XML PATH('YourElement'), ROOT('Root')
This would give something like
<Root>
<YourElement Attribute="someValue">
<z>
<NodeA>text</NodeA>
</z>
</YourElement>
</Root>
Read more about it here:
Simple Example of Creating XML File Using T-SQL
Using XML Serialization with SQL's FOR XML PATH
Your example is not doing what is requested.
request:
<Root attribute="someValue">
<YourElement>
<z>
<NodeA>text</NodeA>
</z>
</YourElement>
</Root>
your answer:
<Root>
<YourElement Attribute="someValue">
<z>
<NodeA>text</NodeA>
</z>
</YourElement>
</Root>
I'm doing something similar and using PowerShell to scrub the file before saving it:
scrub reason 1: https://connect.microsoft.com/SQLServer/feedback/details/265956/suppress-namespace-attributes-in-nested-select-for-xml-statements
scrub reason 2: THIS
SELECT
'someValue' AS '#Attribute',
(SELECT TOP 1
'text' as 'z/NodeA'
FROM dbo.Test
WHERE....
FOR XML PATH('YourElement')
)
FOR XML PATH('ROOT');
It should create a xml with ROOT containg attribute and list of ... inside.