Given the following XML all nodes named IsEurozone have to be renamed to HasFxrEuro.
<?xml version="1.0" encoding="utf-8"?>
<MacroScenarios>
<MacroScenario>
<Id>1</Id>
<Name>Macro Scenario 1</Name>
<Scenarios>
<Scenario>
<CountryIsoAlpha3>USA</CountryIsoAlpha3>
<Id>1</Id>
<IsEurozone>true</IsEurozone>
</Scenario>
<Scenario>
<CountryIsoAlpha3>GER</CountryIsoAlpha3>
<Id>2</Id>
<IsEurozone>true</IsEurozone>
</Scenario>
</Scenarios>
</MacroScenario>
</MacroScenarios>
The replace-operation can easily done (thanks to Mikael Erikssons post How to rename XML node name in a SQL Server):
UPDATE [dbo].[MacroScenarioSets] set
[ContentAsXml] =
replace(
replace(
cast(ContentAsXml as nvarchar(max)),
'<IsEurozone>',
'<HasFxrEuro>'),
'</IsEurozone>',
'</HasFxrEuro>')
After that the content of the Scenario node would look like:
<Scenario>
<CountryIsoAlpha3>USA</CountryIsoAlpha3>
<Id>1</Id>
<HasFxrEuro>true</HasFxrEuro>
</Scenario>
But in my case I need a strict alphabetical order of the nodes and so HasFxrEuro must be placed before Id.
My idea was to do something like
UPDATE [dbo].[MacroScenarioSets]
SET ContentAsXml.modify('insert
<HasFxrEuro>{(/MacroScenarios/MacroScenario/Scenarios/Scenario/IsEurozone/text())}</HasFxrEuro>
after (/MacroScenarios/MacroScenario/Scenarios/Scenario/CountryIsoAlpha3)')
and after that delete all old IsEurozone nodes. But XML DML requires a singleton for insert-statements. Is there another way to achieve that with XML DML?
Ok finally I got it running by manually walking through the XML document:
The solution is very slow. But I have no other idea how to solve this in SQL.