XQuery, если существует условная вставка / замена - PullRequest
3 голосов
/ 22 июля 2010

Как будет выглядеть XQuery, чтобы проверить, существует ли узел, и если он все-таки выполняет оператор замены, если нет, то оператор вставки?

Вот что я имею в виду. Я хочу сохранить, прочитал ли пользователь важное сообщение в XML. Вот как будут выглядеть данные.

<usersettings>
    <message haveRead="0" messageId="23" ></message>
    <message haveRead="1" messageId="22" ></message>
</usersettings>

В основном этот XML говорит мне, что пользователь прочитал одно сообщение, в то время как другое сообщение все еще необходимо просмотреть / прочитать.

Я хочу объединить мою вставку / замену xquery в одно утверждение. Вот что я имел в виду.

UPDATE WebUsers SET UserSettings.modify('

        declare default element namespace "http://www.test.com/test"; 

        IF a node exists with the messageId
            code to replace node with new update
        ELSE
            code to insert a new node with the provided variables
        ')

        WHERE Id = @WebUserId

1 Ответ

5 голосов
/ 10 августа 2010

Я не нашел действительно удовлетворительного способа сделать это, но один из них может сработать для вас.Мне больше нравится первая техника, но меня раздражает, что я не нашел более элегантного способа сделать это.

Убедитесь, что узел всегда существует первым

DECLARE @messageID int;
SET @messageID=24;

DECLARE @myDoc xml;
SET @myDoc = 
'<usersettings>
    <message haveRead="0" messageId="23" >msg</message>
    <message haveRead="1" messageId="22" >msg</message>
</usersettings>';
SELECT @myDoc;


SET @myDoc.modify('
    insert
    if (count(//message[@messageId=sql:variable("@messageID")]) = 0)
    then <message haveRead="0">new msg</message>
    else()
         as last into (/usersettings)[1]
');

SELECT @myDoc;

--now do the rest, safe that the node exists

Переключение

DECLARE @myDoc xml;
SET @myDoc = 
'<usersettings>
    <message haveRead="0" messageId="23" >msg</message>
    <message haveRead="1" messageId="22" >msg</message>
</usersettings>';
SELECT @myDoc;

DECLARE @messageID int;
SET @messageID=23;

IF @myDoc.exist('//message[@messageId=sql:variable("@messageID")]') = 1
BEGIN
    SET @myDoc.modify('replace value of (//message[@messageId=sql:variable("@messageID")]/text())[1]
                       with "test"')
END
ELSE
BEGIN
    SET @myDoc.modify('insert <message haveRead="0">new msg</message>
                       into (/usersettings)[1]')
END

SELECT @myDoc;
...