how to get values inside an xml column, when it's of type nvarchar - sql

My question is similar to this one: Choose a XML node in SQL Server based on max value of a child element
except that my column is NOT of type XML, it's of type nvarchar(max).
I want to extract the XML node values from a column that looks like this:
<Data>
<el1>1234</el1>
<el2>Something</el2>
</Data>
How can I extract the values '1234' and 'Something' ?
doing a convert and using the col.nodes is not working.
CONVERT(XML, table1.col1).value('(/Data/el1)[1]','int') as 'xcol1',
After that, I would like to do a compare value of el1 (1234) with another column, and update update el1 as is. Right now I'm trying to just rebuild the XML when passing the update:
ie
Update table set col1 ='<Data><el1>'+#col2+'</el1><el2>???</el2>

You've got to tell SQL Server the number of the node you're after, like:
(/Data/el1)[1]
^^^
Full example:
declare #t table (id int, col1 varchar(max))
insert #t values (1, '<Data><el1>1234</el1><el2>Something</el2></Data>')
select CAST(col1 as xml).value('(/Data/el1)[1]', 'int')
from #t
-->
1234
SQL Server provides a modify function to change XML columns. But I think you can only use it on columns with the xml type. Here's an example:
declare #q table (id int, col1 xml)
insert #q values (1, '<Data><el1>1234</el1><el2>Something</el2></Data>')
update #q
set col1.modify('replace value of (/Data/el1/text())[1] with "5678"')
select *
from #q
-->
<Data><el1>5678</el1><el2>Something</el2></Data>
At the end of the day, SQL Server's XML support makes simple things very hard. If you value maintainability, you're better off processing XML on the client side.

Related

How to insert an attribute into xml data which is saved as nvarchar(max)

Let's say there is the following XML data and I want to add an attribute into salary like currency="INR":
<employee>
<salary amount="6000"/>
</employee>
If this data is stored in a column of type XML, then another attribute is being added easily just by using this code snippet:
UPDATE TABLENAME
SET COLUMNNAME.modify('insert attribute currency{"INR"} into (/employee/salary)[1]')
and if this data is stored in a column of type nvarchar(max), then the following query is not working even after casting the data as xml:
UPDATE TABLENAME
SET CAST(CAST(COLUMNNAME AS VARCHAR(MAX)) AS XML).modify('insert attribute currency{"INR"} into (/employee/salary)[1]')
So, help me to resolve second point as I have a column as nvarchar and I need to insert an attribute into saved xml data.
modify() Method works only with variable/column directly and can only used in the SET clause.
So, to solve this since you are storing your data as NVARCHAR, you have two choices:
Alter your table and add a new column with XML datatype, move the data to it from your column, and then UPDATE the data using modify()
Create/declare a table to store your data as XML and do the UPDATE.
Here is an example for what you provide:
CREATE TABLE T
(
Value NVARCHAR(MAX)
);
INSERT INTO T
SELECT N'<employee>
<salary amount="6000"/>
</employee>';
DECLARE #V XML;
SELECT #V = CAST(Value AS XML)
FROM T;
SET #V.modify('insert attribute currency{"INR"} into (/employee/salary)[1]');
UPDATE T
SET Value = CAST(#V AS NVARCHAR(MAX));
SELECT * FROM T;
Live demo

Easiest way to query a SQL Server 2008 R2 XML data type?

I need to get a node value in an XML data type column.
<CustomContentData>
<prpIsRSSFeed>false</prpIsRSSFeed>
</CustomContentData>
How is this done in SQL Server?
The column name is ClassXML
Use XQuery, a simple example with your data would be:
DECLARE #T TABLE (ClassXML XML);
INSERT #T (ClassXML)
VALUES ('<CustomContentData>
<prpIsRSSFeed>false</prpIsRSSFeed>
</CustomContentData>');
SELECT t.ClassXML.value('CustomContentData[1]/prpIsRSSFeed[1]', 'VARCHAR(5)')
FROM #T AS t;
If the column is already XML data type in SQL Server, then the code below should work by using the value function with XPATH. If it's stored as a varchar, you'd just need to replace ClassXML.value with CONVERT(XML, ClassXML).value. Hope this helps!
DECLARE #Data TABLE (ClassXML XML)
INSERT #Data VALUES ('<CustomContentData><prpIsRSSFeed>false</prpIsRSSFeed></CustomContentData>')
SELECT
CONVERT(BIT, CASE WHEN ClassXML.value ('(/CustomContentData/prpIsRSSFeed)[1]',
'VARCHAR(50)') = 'true' THEN 1 ELSE 0 END) AS IsRssFeed
FROM #Data
Yields output
IsRssFeed
---------
0

Xquery to return rows with restricted nodes

I have a table where a column contains XML data. Now i want to retrieve those xml data with restriction of nodes. Kindly see the following example for more explanation on my scenario,
declare #table table (id int, xmlfield xml) insert into #table select 1,'<Root xmlns="">
<Sample>
<Issue>
<Level>one</Level>
<Descp>First Example</Descp>
</Issue>
<Issue>
<Level>two</Level>
<Descp>Second Example</Descp>
</Issue>
</Sample> </Root>'
select * from #table
Now i need the following result set
Id XMLfield
1 first example
ie, for the selected level,i need the decription for it. More clearly, the node should be restricted for <level>one</level>
(need: What is the description for level one ?)
thanks in advance
Have a look at the xml Data Type Methods
select id,
xmlfield.value('(//Issue[Level = "one"]/Descp/text())[1]', 'varchar(100)') as XMLField
from #table
The XQuery you're looking for is
//Issue[Level = "one"]/Descp/data()

Select SQL Query to get xml node values from ntext column?

I want to get one xml node value from NTEXT column which contains xml based on where clause quering on another xml node value.
RDBMS Type: Microsoft SQL Server T-SQL
Here: I want to get Code node value based on StoreId where clause value. How do I get it?
Input: 100
Output:ABCDE
For example:
<root>
<StoreProfile>
<General>
<StoreId>100</StoreId>
<Code>ABCDE</Code>
</General>
</StoreProfile>
</root>
If you are using SQL Server 2005 or 2008 you can use XQuery like so:
For more on XQuery see XQuery Language Reference
DECLARE #storeId INT
SET #storeId = 100
CREATE TABLE #TestTable
(
xmlColumn NTEXT
)
INSERT INTO #TestTable (xmlColumn) Values('<root><StoreProfile><General><StoreId>100</StoreId><Code>ABCDE</Code></General></StoreProfile></root>')
INSERT INTO #TestTable (xmlColumn) Values('<root><StoreProfile><General><StoreId>200</StoreId><Code>FGHIJ</Code></General></StoreProfile></root>')
SELECT
StoreProfile.value('Code[1]', 'nvarchar(10)') as Code
FROM #TestTable
CROSS APPLY (SELECT CAST(xmlColumn AS XML)) AS A(B)
CROSS APPLY A.B.nodes('//root/StoreProfile/General[StoreId = sql:variable("#storeId")]') AS StoreProfiles(StoreProfile)
DROP TABLE #TestTable

How to get Sql Server XML variable into TEXT column

I need to update an XML document stored in a Microsoft SQL Server database, however the vendor of the product chose to store the XML in a TEXT column.
I've been able to extract the TEXT into an XML-type variable and perform the update I need on the xml within this variable, but when I try to UPDATE the column to push the change back to the database, I run into trouble.
Looking through the documentation it appears that it's not possible to simply CAST/CONVERT an XML type variable to insert it into a TEXT column, but I would think there is some way to extract the xml "string" from the XML-type variable and UPDATE the column using this value.
Any suggestions are appreciated, but I would like to keep the solution pure SQL that it can be run directly (no C# custom function, etc.); just to keep the impact on the database minimal.
(note: isn't it a bit absurd that you can't just CAST XML as TEXT? I'm just saying...)
Casting the XML as VARCHAR(MAX) works.
declare #xml xml
declare #tblTest table (
Id int,
XMLColumn text
)
insert into #tblTest
(Id, XMLColumn)
values
(1, '<MyTest><TestNode>A</TestNode></MyTest>')
set #xml = '<MyTest><TestNode>A</TestNode><TestNode>B</TestNode></MyTest>'
update #tblTest
set XMLColumn = cast(#xml as varchar(max))
where Id = 1
select Id, XMLColumn from #tblTest