【问题标题】:SQL replace a null xml valueSQL 替换一个空 xml 值
【发布时间】:2017-07-05 11:01:44
【问题描述】:

我是 sql 初学者,不知道如何解决我的问题。

我有一个包含项目的表,一列包含 xml 值。我想检查一个字段是否存在并更新它。

我找到了一种修改现有 xml 值的方法,但是当它为 NULL 时它不起作用

这是我的代码:

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;

【问题讨论】:

    标签: sql-server tsql xpath xquery xml-dml


    【解决方案1】:

    在这种情况下,大多数情况下最简单的方法是丢弃现有元素并将其作为新元素插入:

    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;
    

    【讨论】:

      【解决方案2】:

      遵循您的代码结构

      SELECT @xml=IDA_Xml,
         @isData = IDA_Xml.exist('(/Root/Data[1]/text())[1]')
      FROM DATA
      WHERE IDA_UId=@guid
      
      If (@xml is NULL)
      BEGIN
          UPDATE ItemData SET IDA_Xml =  CAST('<root/>' as XML)
          WHERE IDA_UId = @guid;
          SET @isData = 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;
      

      但我最好使用单次更新而不是前两次更新来重组它

      SET IDA_Xml =  CAST('construct your entire xml here' as XML)
      

      【讨论】:

      • 没错,单次更新效果更好。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      相关资源
      最近更新 更多