2010-10-04 39 views
4

我有一個包含XML列的表, 我想更新xml以插入屬性,或者如果該屬性已存在,則更改屬性值。XQuery在單個SQL更新命令中添加或替換屬性

比方說,開始的XML是:< d />

插入:

UPDATE Table 
set XmlCol.modify('insert attribute att {"1"} into /d[1]') 

改變:如果屬性已經存在

UPDATE Table 
set XmlCol.modify('replace value of /d[1]/@att with "1"') 

插入會失敗,如果屬性不存在,替換將失敗。 我試圖使用'如果',但我不認爲它可以工作,我得到的錯誤:「XQuery [修改()]:'屬性'附近的語法錯誤,預計'其他'。

IF嘗試

UPDATE Table 
set XmlCol.modify('if empty(/d[1]/@att) 
        then insert attribute att {"1"} into /d[1] 
        else replace value of /d[1]/@att with "1"') 

目前我選擇XML到一個變量,然後使用T-SQL,然後更新與新的XML列修改它,這需要我去鎖定該行的交易對於數據庫而言可能更昂貴。

回答

2

從我所知道的,你不能用單一語句來做到這一點。您可以使用exist() method通過兩條更新語句來完成該操作。

DECLARE @TestTable TABLE 
(
    Id int, 
    XmlCol xml 
); 

INSERT INTO @TestTable (Id, XmlCol) 
VALUES 
    (1, '<d att="1" />'), 
    (2, '<d />'), 
    (3, '<d att="3" />'); 

SELECT * FROM @TestTable; 

UPDATE @TestTable 
SET XmlCol.modify('replace value of /d[1]/@att with "1"') 
WHERE XmlCol.exist('(/d[1])[not(empty(@att))]') = 1; 

UPDATE @TestTable 
SET XmlCol.modify('insert attribute att {"1"} into /d[1]') 
WHERE XmlCol.exist('(/d[1])[empty(@att)]') = 1; 

SELECT * FROM @TestTable; 

從最終選擇輸出爲:

Id   XmlCol 
----------- ------------------- 
1   <d att="1" /> 
2   <d att="1" /> 
3   <d att="1" /> 
1

沒有比湯米一個稍微好一點的辦法:

DECLARE @TestTable TABLE 
(
    Id int, 
    XmlCol xml 
); 

INSERT INTO @TestTable (Id, XmlCol) 
VALUES 
    (1, '<UserSettings> </UserSettings>'), 
    (2, '<UserSettings><timeout>3</timeout> </UserSettings>'), 
    (3, '<UserSettings> </UserSettings>'); 

UPDATE @TestTable 
SET XmlCol.modify('replace value of (/UserSettings/timeout/text())[1] with "1"') 
WHERE Id = 3 and XmlCol.exist('/UserSettings/timeout') = 1; 
IF @@ROWCOUNT=0 
    UPDATE @TestTable 
    SET XmlCol.modify('insert <timeout>5</timeout> into (/UserSettings)[1] ') 
    WHERE Id = 3; 

SELECT * FROM @TestTable; 

的解決方案是湯米和簡單的SQL和所需的組合如果該列存在,則只有1個SQL UPDATE。湯米斯總是會恢復兩次更新。