鉴于以下XML,所有名为 IsEurozone 的节点都必须重命名为 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>
替换操作很容易完成(感谢Mikael Erikssons发布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>')
之后,Scenario节点的内容如下所示:
<Scenario>
<CountryIsoAlpha3>USA</CountryIsoAlpha3>
<Id>1</Id>
<HasFxrEuro>true</HasFxrEuro>
</Scenario>
但在我的情况下,我需要严格按字母顺序排列节点,因此必须在 Id 之前放置 HasFxrEuro 。
我的想法是做一些像
这样的事情UPDATE [dbo].[MacroScenarioSets]
SET ContentAsXml.modify('insert
<HasFxrEuro>{(/MacroScenarios/MacroScenario/Scenarios/Scenario/IsEurozone/text())}</HasFxrEuro>
after (/MacroScenarios/MacroScenario/Scenarios/Scenario/CountryIsoAlpha3)')
之后删除所有旧的 IsEurozone 节点。但XML DML需要inserton语句的单例。有没有其他方法可以通过XML DML实现这一目标?
答案 0 :(得分:0)
好的,最后我通过手动浏览XML文档来运行它:
declare @scenarioCursor int = 1
declare @macroScenarioCursor int = 1
while 1 = 1
begin
-- Add HasFxrEuro with the value of IsEurozone
UPDATE @myxml
SET content.modify('
insert
<HasFxrEuro>{(/MacroScenarios/MacroScenario[sql:variable("@macroScenarioCursor")]/Scenarios/Scenario[sql:variable("@scenarioCursor")]/IsEurozone[1]/text())}</HasFxrEuro>
after ((/MacroScenarios/MacroScenario[sql:variable("@macroScenarioCursor")]/Scenarios/Scenario[sql:variable("@scenarioCursor")]/CountryIsoAlpha3))[1]')
WHERE content.exist('
(/MacroScenarioSet/MacroScenarios/MacroScenario[sql:variable("@macroScenarioCursor")]/Scenarios/Scenario[sql:variable("@scenarioCursor")])') = 1
if @@ROWCOUNT = 0
begin
-- the end
if @scenarioCursor = 1
break;
else
-- increment cursor over MacroScenario, reset cursor over Scenario
begin
SET @macroScenarioCursor = @macroScenarioCursor + 1
SET @scenarioCursor = 1
end
end
else
begin
-- HasFxrEuro has been added remove IsEurozone
UPDATE @myxml
SET content.modify('
delete (/MacroScenarios/MacroScenario[sql:variable("@macroScenarioCursor")]/Scenarios/Scenario[sql:variable("@scenarioCursor")]/IsEurozone)')
-- increment Scenario cursor
SET @scenarioCursor = @scenarioCursor + 1
end
end
解决方案非常缓慢。但我不知道如何在SQL中解决这个问题。