Как пометить выражение XQuery как определитель c? (Чтобы сохранить вычисляемый столбец из значений XML) - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть таблица со столбцом типа xml (DOCUMENT <MyDocType>), для которой я определил очень маленькую схему. Примерно XML имеет такую ​​простую форму:

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

То есть root с 0 или более дочерними элементами типа a или b. Вот и все.

Я хотел бы иметь постоянный вычисляемый столбец из этих данных, из объединенных в строку строк значений каждого дочернего элемента 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

Но при использовании этой функции в качестве источника постоянного столбца база данных жалуется, что функция не определена c.

Я бы сказал, что эта функция, по моей человеческой интуиции, детерминирована c. Но база данных, похоже, не согласна со мной. Я понимаю, что, возможно, XQuery может делать какие-то недетерминированные c вещи, но разве эта простая возможность портит все запросы XQuery недетерминированностью?

Есть ли способ сообщить базе данных, что " эй, эта функция, которая принимает XML и возвращает строку, является детерминированной c - позвольте мне извлечь из нее постоянный вычисляемый столбец "?

1 Ответ

2 голосов
/ 21 апреля 2020
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
...