For xml, type

Результаты запроса for xml теперь доступны на сервере и могут быть автоматически представлены как встроенный тип xml. Фактически, вы можете не указывать команду type, так как преобразование из строки в XML-тип делается неявно, т.е. две следующие команды эквивалентны:

--без ключевого слова typedeclare @x xmlset @x = (select * from sys.indexes for xml auto) --с ключевым словом typedeclare @x xmlset @x = (select * from sys.indexes for xml auto, type)

Однако в первом случае возвращается строка, которая затем преобразуется в XML-тип, а во втором – сразу XML-тип. Различие становится более очевидным в следующем примере:

select (select * from sys.indexes for xml auto, type)::query('//*')

Подобная запись возможна потому, что результатом выборки с ключевым словом type является XML-тип. Без использования ключевого слова type сервер вернет ошибку.

Вложенные запросы for xml

Раньше нельзя было выполнять вложенные запросы, возвращающие xml. Теперь это стало возможным. Например:

select name, object_id, (select name, index_id from sys.indexes [index] where [index].object_id = object.object_id for xml auto, type)from sys.objects objectfor xml auto

Вложенный запрос возвращает тип xml, и серверу абсолютно безразлично, как он был получен. Т.е. с тем же успехом можно написать так:

declare @xml xmlset @xml = '<root/>'select name, object_id, @xml from sys.objects object for xml auto

При этом содержимое переменной @xml вставляется в результирующий XML-фрагмент (более точно: все элементы верхнего уровня XML-документа вложенного запроса копируются в результирующий фрагмент как дочерние узлы элемента, обозначающего строку выборки).

XSINIL

Теперь пустое значение можно представлять с помощью стандартного механизма, принятого в XML для обозначения значения NULL. Суть проблемы заключается в том, что в режиме for xml auto, elements поля со значением NULL просто не попадают в результирующий XML-фрагмент. Например:

select top 4 object_id, case when object_id % 2 = 0 then null else object_id end obj from sys.indexes for xml auto, elements

Возвращает:

<sys.indexes> <object_id>133575514</object_id></sys.indexes><sys.indexes> <object_id>677577452</object_id></sys.indexes><sys.indexes> <object_id>677577452</object_id></sys.indexes><sys.indexes> <object_id>693577509</object_id> <obj>693577509</obj></sys.indexes>

Как видите, для первых трех строк элемент obj отсутствует, потому что равен NULL. Для того чтобы передать информацию о том, что он равен NULL, в XML-документ, необходимо добавить ключевое слово xsinil следующим образом:

select top 4 object_id, case when object_id % 2 = 0 then null else object_id end obj from sys.indexes for xml auto, elements xsinil

Теперь все в порядке (изменения выделены):

<sys.indexes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <object_id>133575514</object_id> <obj xsi:nil="1" /></sys.indexes><sys.indexes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <object_id>677577452</object_id> <obj xsi:nil="1" /></sys.indexes><sys.indexes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <object_id>677577452</object_id> <obj xsi:nil="1" /></sys.indexes><sys.indexes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <object_id>693577509</object_id> <obj>693577509</obj></sys.indexes>

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: