Click here to Skip to main content
15,899,679 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
e.g.
DECLARE @Employee TABLE(empXML XML);
DECLARE @OldEmployeeId INT=103, @NewEmployeeId INT=999;

INSERT INTO @Employee VALUES('<root><Employee Id="100"/><Employee Id="102"/><Employee Id="103"/><Employee Id="104"/>')

SELECT * FROM @Employee

I want to update value of Employee Id to 999 where Employee Id =103.

What I have tried:

I tried this but no luck.

UPDATE @Employee SET
empXML.modify('replace value of (ROOT/Employee/@Id)[1] with sql:variable("@NewEmployeeId")')
WHERE empXML.value('(ROOT/Employee/@Id)[1]', 'INT') = @OldEmployeeId
Posted
Updated 21-Dec-19 23:06pm
v2

1 solution

Your XML is invalid - the <root> node is not closed.

XML is case-sensitive. In the inserted XML, the root element is called <root>, so an XPath query for ROOT isn't going to match it.

Your WHERE clause extracts the ID of the first <Employee> node, which is 100. That is not equal to your @OldEmployeeId variable, so there are no rows to update.

Your replace value of statement is replacing the ID of the first <Employee> node, which is not what you're trying to do.

Change your UPDATE query to:
SQL
UPDATE @Employee 
SET empXML.modify('replace value of (root/Employee[@Id = sql:variable("@OldEmployeeId")]/@Id)[1] with sql:variable("@NewEmployeeId")')
WHERE empXML.exist('root/Employee[@Id = sql:variable("@OldEmployeeId")]') = 1;

replace value of (XML DML)[^]
exist() Method (xml Data Type)[^]
XPath Reference[^]
 
Share this answer
 
Comments
xpertzgurtej 26-Jan-17 23:36pm    
thanks for your help..It worked same as i want..
Member 11996223 8-Dec-19 22:43pm    
@Richard Deeming - can you please help me on below question from your solution?

empXML.modify('replace value of (root/Employee[@Id = sql:variable("@OldEmployeeId")]/@Id)

is there any possibilities to have a condition wild card checking. I mean, You are having condition like this [@Id = sql:variable("@OldEmployeeId")]. its checking exact value. I need, [@Id like %sql:variable("@OldEmployeeId")%].

How to handle this situation. Because, i having value with whitespace. otheriwse how to trim.

Thanks for the support.
Richard Deeming 9-Dec-19 5:56am    
There doesn't seem to be a Like operator, but there is a contains function:
contains Function (XQuery) - SQL Server | Microsoft Docs[^]
WHERE empXML.exist('root/Employee[contains(@Id, sql:variable("@OldEmployeeId"))]') = 1


However, I'm not sure this would do what you want. If you were searching for 42, it would also return records with an ID of 1422, for example.

You might need to "shred" the XML and run the search in SQL instead.
Member 11996223 22-Dec-19 5:16am    
@Richard deeming, Thanks. I will check. hope it will help me.
Member 11996223 22-Dec-19 8:59am    
set @xmld.modify('replace value of (/Root/Identification[contains(Age,sql:variable("@age"))]/name/text())[1] with "123"')

while i am trying to run about code. i am getting error like,
"XQuery [modify()]: 'contains()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'"

- please guide me on this

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900