我有一个名为Schemes的表,其中的XML
结构化文件以VARCHAR
的形式存储在列中。XML文件如下所示,
<Process>
<Timers>
<Timer Name="SendNotificationStaffLevel1" Type="Interval" Value="25m"
NotOverrideIfExists="true" />
<Timer Name="SendNotificationSecretaryLevel1" Type="Interval" Value="600m"
NotOverrideIfExists="true" />
<Timer Name="ReAssigningRequestToSecretaryLevel1" Type="Interval"
Value="605m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationStaffLevel2" Type="Interval" Value="5m"
NotOverrideIfExists="true" />
<Timer Name="SendNotificationSecretaryLevel2" Type="Interval" Value="10m"
NotOverrideIfExists="true" />
<Timer Name="ReAssigningRequestToSecretaryLevel2" Type="Interval"
Value="12m" NotOverrideIfExists="true" />
<Timer Name="DeactivateUrlOfFileResubmission" Type="Interval" Value="15m"
NotOverrideIfExists="true" />
</Timers>
</process>
我需要通过提供名称属性viz来更新每个计时器的值。 “ SendNotificationStaffLevel1”作为存储过程的参数。
我尝试了
update YourTable set
XMLText.modify('replace value of (/Process/Timers/Timer/@Value)[1] with "40m"')
where XMLText.value('(/Process/Timers/Timer/@Value)[1]', 'varchar') = 25m
但是我需要指定name属性来更新值。如何完成?谢谢。
答案 0 :(得分:1)
您可以像下面这样将属性的过滤器值添加到Xpath
的谓词中:
DECLARE @xml XML=
'<Process>
<Timers>
<Timer Name="SendNotificationStaffLevel1" Type="Interval" Value="25m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationSecretaryLevel1" Type="Interval" Value="600m" NotOverrideIfExists="true" />
<Timer Name="ReAssigningRequestToSecretaryLevel1" Type="Interval" Value="605m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationStaffLevel2" Type="Interval" Value="5m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationSecretaryLevel2" Type="Interval" Value="10m" NotOverrideIfExists="true" />
<Timer Name="ReAssigningRequestToSecretaryLevel2" Type="Interval" Value="12m" NotOverrideIfExists="true" />
<Timer Name="DeactivateUrlOfFileResubmission" Type="Interval" Value="15m" NotOverrideIfExists="true" />
</Timers>
</Process>';
DECLARE @Name VARCHAR(100)='SendNotificationStaffLevel1';
SET @xml.modify('replace value of (/Process/Timers/Timer[@Name=sql:variable("@Name")]/@Value)[1] with "40m"');
SELECT @xml;
您可以将Xpath
读为:
<Process>
开始<Timers>
,然后深入<Timer>
[1]
)事件@Value
您可以轻松调整以上内容以使其适用于表的列,但是:
如果XML另存为VARCHAR(x)
,则必须欺骗它。 .modify()
需要本机XML类型,因此您无法更新强制转换列。我建议写一个中间表,在那里做更新然后写回去:
一个样机表:
DECLARE @mockup TABLE(ID INT IDENTITY, YourXmlAsString VARCHAR(MAX));
INSERT INTO @mockup VALUES
('<Process>
<Timers>
<Timer Name="SendNotificationStaffLevel1" Type="Interval" Value="25m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationSecretaryLevel1" Type="Interval" Value="600m" NotOverrideIfExists="true" />
<Timer Name="ReAssigningRequestToSecretaryLevel1" Type="Interval" Value="605m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationStaffLevel2" Type="Interval" Value="5m" NotOverrideIfExists="true" />
<Timer Name="SendNotificationSecretaryLevel2" Type="Interval" Value="10m" NotOverrideIfExists="true" />
<Timer Name="ReAssigningRequestToSecretaryLevel2" Type="Interval" Value="12m" NotOverrideIfExists="true" />
<Timer Name="DeactivateUrlOfFileResubmission" Type="Interval" Value="15m" NotOverrideIfExists="true" />
</Timers>
</Process>');
-将强制转换的列写入临时表中
SELECT ID
,YourXmlAsString --<-- You don't need this actually
,CAST(YourXmlAsString AS XML) YourXmlAsXml
INTO #tmpTable
FROM @mockup ;
-进行更新
DECLARE @Name VARCHAR(100)='SendNotificationStaffLevel1';
UPDATE #tmpTable
SET YourXmlAsXml .modify('replace value of (/Process/Timers/Timer[@Name=sql:variable("@Name")]/@Value)[1] with "40m"');
-更新原始表
UPDATE t
SET YourXmlAsString=CAST(tmp.YourXmlAsXml AS VARCHAR(MAX))
FROM #tmpTable tmp
INNER JOIN @mockup t ON tmp.ID=t.ID;
-检查结果
SELECT * FROM @mockup;
如果有机会将列的类型更改为XML,那么您确实应该这样做...
答案 1 :(得分:0)
我发现的示例有一些不同之处
UPDATE HR_XML
SET Salaries.modify('replace value of
(/Salaries/Marketing/Employee[@ID=("2")]/Salary/text())[1] with ("60000")')
GO
对于您的情况,应该是
update YourTable set
XMLText.modify('replace value of
(/Process/Timers/Timer[@Name=("SendNotificationSecretaryLevel2")]/@Value)[1] with "40m"')
GO
不过,我不确定更新的位置。