0

I need to replace a value in xml using SQL, challenge here I am facing is the value which I want to replace is not on a specific xpath, same value is on different nodes and the xpath is also different, so basically I want to find and replace a value.

example:

<data>
  <policy>
    <Effectivedate>2018-04-05</Effectivedate>
    <TermStartDate>2018-04-05</TermStartDate>
    <Line>
        <Risk>
            <Coverage>
                <Type>1</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
            <Coverage>
                <Type>2</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
            <Coverage>
                <Type>3</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
        </Risk>
    </Line>
  </policy>
 </data>

In above example I need to replace date 2018-04-05 with 2018-04-06

Please can anyone help here.

7
  • what database engine? Commented May 12, 2018 at 23:40
  • Please add a tag for the RDBMS you are using, as string operations differ widely among them. Also, can you edit above to show a few samples of the XML and how the values must change? Commented May 12, 2018 at 23:40
  • If the XML is simple without attributes and without irregular whitespace, it might be easy. Otherwise it might be challenging. Commented May 12, 2018 at 23:41
  • Please share instances of your data, your attempted code. And why do you need to do this with SQL? Commented May 12, 2018 at 23:41
  • Updated with an example Commented May 12, 2018 at 23:59

2 Answers 2

6

If you have to replace elements in different paths you can cast the xml to a *char and use replace:

declare @xml xml='<data> <policy> <Effectivedate>2018-04-05</Effectivedate> <TermStartDate>2018-04-05</TermStartDate> <Line> <Risk> <Coverage> <Type>1</Type> <coverstartdate>2018-04-05</coverstartdate> </Coverage> <Coverage> <Type>2</Type> <coverstartdate>2018-04-05</coverstartdate> </Coverage> <Coverage> <Type>3</Type> <coverstartdate>2018-04-05</coverstartdate> </Coverage> </Risk> </Line> </policy> </data>'

select cast (replace (cast(@xml as nvarchar(max)), '2018-04-05','2018-04-06') as xml)

Result:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

4

The .modify() function will not allow you to change more than one value per call. You might do this in string level with REPLACE() but this could have side-effects...

What you can do (but this won't be fast) is to use .modify() in a loop, until all occurances are replaced, something like this:

DECLARE  @xml XML=
N'<data>
  <policy>
    <Effectivedate>2018-04-05</Effectivedate>
    <TermStartDate>2018-04-05</TermStartDate>
    <Line>
        <Risk>
            <Coverage>
                <Type>1</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
            <Coverage>
                <Type>2</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
            <Coverage>
                <Type>3</Type>
                <coverstartdate>2018-04-05</coverstartdate>
            </Coverage>
        </Risk>
    </Line>
  </policy>
 </data>';

WHILE @xml.exist(N'//*[text()="2018-04-05"]')=1
BEGIN
    SET @xml.modify(N'replace value of (//*[text()="2018-04-05"]/text())[1] with "2018-04-06"');
END
SELECT @xml;

This is ugly (due to the loop) and slow, but - at least - it is XQuery.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.