SQL Server XML 数据 - 如何插入(如果为空)或更新(如果不为空)

问题描述 投票:0回答:1

我有一个包含表的 xml 变量。该表有许多列和一行。在前两列中,我需要使用另一个 SP 的结果更新它们的值 - 如果值是空,则插入一个值;如果值已存在,则更新该值。这是我到目前为止所拥有的:

-- Declare xml variable. Either column could be empty or populated. They are shown empty here.
DECLARE @x xml = N'<?xml version="1.0" encoding="utf-16"?>
<Table>
  <Row>
    <Column></Column>
    <Column></Column>
  </Row>
</Table>'

-- View xml table prior to modifications
SELECT tbl.col.value('Column[1]/text()[1]', 'int') 'id'
      ,tbl.col.value('Column[2]/text()[1]', 'datetime2(2)') 'date'
FROM @x.nodes('//Table/Row') tbl(col)

-- Declare new id and date variables. This will come from another SP. I've made it static to simplify the example.
DECLARE @id int = 24
DECLARE @date datetime2(2) = sysutcdatetime()

-- If id is empty, insert the id value. Otheriwse, update the id value.
IF (SELECT tbl.col.value('Column[1]/text()[1]', 'int') 'id'
    FROM @x.nodes('//Table/Row') tbl(col)) IS NULL

    SET @x.modify('insert text{sql:variable("@id")} into (//Table/Row/Column)[1]')

ELSE
    
    SET @x.modify('replace value of (//Table/Row/Column/text())[1] with sql:variable("@id")')

-- If date is empty, insert the date value. Otherwise, update the date value
IF (SELECT tbl.col.value('Column[2]/text()[1]', 'datetime2(2)') 'date'
    FROM @x.nodes('//Table/Row') tbl(col)) IS NULL

    SET @x.modify('insert text{sql:variable("@date")} into (//Table/Row/Column)[2]')

ELSE
    
    SET @x.modify('replace value of (//Table/Row/Column/text())[2] with sql:variable("@date")')

-- View xml table after modifications
SELECT tbl.col.value('Column[1]/text()[1]', 'int') 'id'
      ,tbl.col.value('Column[2]/text()[1]', 'datetime2(2)') 'date'
FROM @x.nodes('//Table/Row') tbl(col)

这似乎有效;但是,我想知道是否有一种方法可以在修改函数本身中写入条件(即,如果为空,则插入;否则,替换值)?换句话说,我可以避免 SQL IF...ELSE 语句并使用一个 SET 语句吗?另外,有没有办法在同一个修改函数中更新两列,还是必须分开?

提前致谢!

sql-server xml-dml xml.modify
1个回答
0
投票

请尝试利用 SQL Server XQuery 及其 FLWOR 表达式的以下解决方案。

对于此方法,XML 值是否存在并不重要。

SQL

-- Declare xml variable. Either column could be empty or populated. They are shown empty here.
DECLARE @x xml = N'<?xml version="1.0" encoding="utf-16"?>
<Table>
  <Row>
    <Column></Column>
    <Column></Column>
  </Row>
</Table>';

-- View xml table prior to modifications
SELECT tbl.col.value('Column[1]/text()[1]', 'int') 'id'
      ,tbl.col.value('Column[2]/text()[1]', 'datetime2(2)') 'date'
FROM @x.nodes('//Table/Row') tbl(col);

-- Declare new id and date variables.
DECLARE @id int = 24;
DECLARE @date datetime2(2) = sysutcdatetime();

SET @x = @x.query('<Table>
{
   for $y in /Table/Row
   return <Row>
   {
        for $z in $y/*
        return if ($z is $y/*[1]) then 
                element Column {sql:variable("@id")}
            else
            (
                element Column {sql:variable("@date")}
            )
    }
   </Row>
}
</Table>');

-- View xml table after modifications
SELECT tbl.col.value('Column[1]/text()[1]', 'int') 'id'
      ,tbl.col.value('Column[2]/text()[1]', 'datetime2(2)') 'date'
FROM @x.nodes('//Table/Row') tbl(col);

输出

id 日期
24 2025-01-20 15:39:12.74
© www.soinside.com 2019 - 2024. All rights reserved.