我有一个包含表的 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 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 |