sql-servert-sqlxpathxqueryxml-dml

SQL replace a null xml value


I'm a beginner in sql, and I don't know how to find a solution to my problem.

I have a table with items, a column contains xml value. I want to check if a field exist and update it.

I find a way to modify an existing xml value, but when it's NULL it doesn't work

there is my code :

SELECT @xml=IDA_Xml,
   @isData = IDA_Xml.exist('(/Root/Data[1]/text())[1]')
FROM DATA
WHERE IDA_UId=@guid

If (@xml is NULL)
BEGIN
    -- Create a xml value with <Root></Root>
    -- It will be update later
    -- set isData to 0
END

IF (@isData = 0)
    UPDATE ItemData SET IDA_Xml.modify
    ('
        insert <Data Name = "Info">{sql:variable("@number")}</Data>
        into (/Root/*)[1]
    ')
    WHERE IDA_UId = @guid;
ELSE
    UPDATE ItemData SET IDA_Xml.modify
    ('
        replace value of (/Root/Data[1]/text())[1]
        with    sql:variable("@number")
    ')
    WHERE IDA_UId = @guid;

Solution

  • In this case the easiest approach in most cases is to throw away the existing element and insert it as new:

    DECLARE @mockup TABLE(ID INT IDENTITY, Descr VARCHAR(100),YourXml XML);
    INSERT INTO @mockup VALUES
     ('element exists','<root><element>test</element><SomeOther>blah</SomeOther></root>')
    ,('element doesn''t exist','<root><SomeOther>blah</SomeOther></root>')
    ,('element exists, but empty','<root><element/><SomeOther>blah</SomeOther></root>');
    
    --At the end, all should be `<element>new</element>`
    
    UPDATE @mockup SET YourXml.modify('delete (/root/element)[1]');
    UPDATE @mockup SET YourXml.modify('insert <element>new</element> as first into (/root)[1]');
    
    SELECT * FROM @mockup;