在具有由SQL函数修改的表列值的节点上使用XML修改



我想用普通NVARCHAR列中的值更新sql server xml列中的xml文档的节点。当我直接使用该值时;sql:column("SAPersoon.ACHTERNAAM"(;。但是,如果我想先应用一个函数,比如trim,该怎么办?或者如下面的例子中的子字符串。现在我正在使用交叉应用程序。

是否可以在不需要交叉申请的情况下以更好的方式完成此操作?有没有一种方法可以将sql函数的结果直接提供给XML修改?我找不到这方面的语法。

UPDATE [vault].[Objects] SET 
[Content].modify('replace value of (/Object/Achternaam/text())[1] with (sql:column("x.waarde"))')
FROM [vault].[Objects]
INNER JOIN SAPersoon ON Objects.Id = SAPersoon.Id
CROSS APPLY (VALUES(SUBSTRING(SAPersoon.ACHTERNAAM, 1, 1))) x(waarde)
WHERE [Objects].[Content].exist('/Object/Achternaam') = 1
AND [Objects].[Content].value('(/Object/Achternaam/text())[1]', 'nvarchar(255)') <> x.waarde

编辑:

Yithzak的答案对我来说已经很有用了,因为我选择了子字符串函数,因为我认为SQL中不支持等效的XQuery函数。我的错误。所以我需要补充一个额外的标准:(。在使用随机sql用户定义函数的情况下,是否要避免交叉应用。

with (...)子句包含一个属于XML/XQueryContext的表达式。它接受任何合法的XQuery函数调用。因此,对于您的特定情况,无需使用CROSS APPLY

请检查以下概念示例。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, city VARCHAR(30), xmldata XML);
INSERT INTO @tbl (city, xmldata) VALUES
('Miami', N'<root>
<city>Hollywood</city>
</root>');
-- DDL and sample data population, end
-- before
SELECT * FROM @tbl;
UPDATE @tbl
SET xmldata.modify('replace value of (/root/city/text())[1] 
with (fn:substring(sql:column("@tbl.city"),1,3))');
-- after
SELECT * FROM @tbl;

输出

<root>
<city>Mia</city>
</root>

编辑

不幸的是,MSSQLServer的XQuery不支持用XQuery编写的UDF。因此,如果您需要应用任何T-SQL udf,则需要使用CROSS/OUTER APPLY

最新更新