如何将XQuery表达式标记为确定性?(为了持久化来自XML值的计算列)



我有一个带有xml (DOCUMENT <MyDocType>)类型列的表,我为它定义了一个非常小的模式。大致上,XML有这样一个简单的形状:

<root>
(<a> | <b>)*
</root>

因此,根具有0个或更多类型为ab的子元素。就是这样。

我希望从这些数据中,从root的每个子级的串联字符串化值中,得到一个持久化的计算列;所以我创建了一个UDF来字符串化每个文档的内容:

create function stringify (@doc xml (document MyDocType))
returns varchar(256)
as begin
return convert(varchar(256), @doc.query('
for $val in /root/*
return string($val)'))
end

但是,当使用此函数作为持久化列的源时,数据库会抱怨该函数不具有确定性。

我想说,根据我的人类直觉,这个函数是确定的。但数据库似乎不同意我的观点。我知道XQuery可能会做一些不确定的事情,但这种可能性会让所有XQuery查询都变得不确定吗?

有没有一种方法可以告诉数据库"嘿,这个接受XML并返回字符串的函数是确定的——让我用它派生一个持久化的计算列"?

create function dbo.xmldata(@thexml xml)
returns nvarchar(max)
with schemabinding, returns null on null input
as
begin
return @thexml.query('for $val in /root/* return string($val)').value('.', 'nvarchar(max)')
--return (@thexml.value('return ./root/*/text()', 'nvarchar(max)'))
end
go
create table dbo.testabc
(
thexml xml,
thestring as dbo.xmldata(thexml) persisted
)
go
insert into dbo.testabc(thexml)
values('<root><a>aaaaa</a><b>bbbbb</b></root>')
go
select * 
from dbo.testabc
go
drop table dbo.testabc
go
drop function dbo.xmldata;
go

最新更新