Поделиться через


Правила по использованию предложения FOR XML

Предложение FOR XML может использоваться в запросах верхнего уровня и вложенных запросах. Предложение FOR XML верхнего уровня можно использовать только в инструкции SELECT. Во вложенных запросах предложение FOR XML можно использовать в инструкциях INSERT, UPDATE и DELETE. Оно также может использоваться в инструкциях присваивания. Например:

DECLARE @x xml
SET @x = (SELECT *
FROM Sales.Customer
FOR XML AUTO, TYPE)
SELECT @x

Обратите внимание, что директива TYPE возвращает результат запроса типа данных xml. Если эта директива отсутствует, результат запроса FOR XML имеет тип nvarchar(max). Затем он преобразуется в тип данных xml и присваивается переменной типа xml.

На предложение FOR XML накладываются следующие ограничения:

  • Предложение FOR XML недопустимо для выборки с использованием предложений COMPUTE BY или FOR BROWSE. Например, следующий запрос возвращает ошибку:

    SELECT TOP 5 SalesOrderID, UnitPrice 
    FROM Sales.SalesOrderDetail 
    ORDER BY SalesOrderID COMPUTE SUM(UnitPrice) BY SalesOrderID
    FOR XML AUTO
    
  • Предложение FOR XML верхнего уровня без директивы TYPE не может использоваться вместе с курсорами.

  • Если в инструкции SELECT, использующей предложение FOR XML, указано имя из четырех частей, в возвращаемом документе имя сервера отсутствует, если запрос выполняется на локальном компьютере. Однако имя сервера возвращается как часть имени, если запрос выполняется на сетевом сервере.
    В качестве примера рассмотрим запрос:

    SELECT TOP 1 LastName
    FROM ServerName.AdventureWorks.Person.Contact
    FOR XML AUTO
    

    Если ServerName — локальный сервер, результат запроса будет таким:

    <AdventureWorks.Person.Contact LastName="Achong" />
    

    Если ServerName — сетевой сервер, результат запроса будет таким:

    <ServerName.AdventureWorks.Person.Contact LastName="Achong" />
    

    Этой возможной неоднозначности можно избежать с помощью такого псевдонима:

    SELECT TOP 1 LastName
    FROM ServerName.AdventureWorks.Person.Contact x
    FOR XML AUTO 
    

    Результат этого запроса будет таким:

    <x LastName="Achong"/>
    

Также имена серверов SQL Server, содержащие символы, недопустимые в именах XML, например пробелы, преобразуются в имена XML таким образом, что недопустимые символы переводятся в представление соответствующими численными сущностями с экранирующим символом.

Есть только два небуквенных символа, которые могут встречаться в имени XML: двоеточие (:) и подчеркивание (_). Так как двоеточие уже зарезервировано для пространств имен, в качестве экранирующего символа используется подчеркивание. Далее перечислены правила кодирования недопустимых символов:

  • Все символы UCS-2, которые не могут входить имена XML в соответствии со стандартом XML 1.0, экранируются как _xHHHH_. Здесь сочетание HHHH будет замещено на четырехразрядный шестнадцатеричный код символа в UCS-2, где самым старшим является первый разряд. Например, имя таблицы Order Details будет закодировано как Order_x0020_Details.

  • Символы, не входящие в диапазон UCS-2 (дополнения UCS-4 в диапазоне от U+00010000 до U+0010FFFF), кодируются как _xHHHHHHHH_. Здесь сочетание HHHHHHHH будет замещено на восьмиразрядный шестнадцатеричный код символа в UCS-4, если используется режим обратной совместимости с SQL Server 2000. Иначе символы кодируются как _xHHHHHH_ для соответствия стандарту SQL-2003.

  • Символ подчеркивания не нуждается в кодировании, если за ним не следует символ x. Например, имя таблицы Order_Details никак не преобразуется.

  • Двоеточие в идентификаторах не кодируется. Поэтому запрос FOR XML может формировать элемент пространства имени и имена атрибутов. Например, следующий запрос формирует атрибут пространства имен с двоеточием в имени:

    SELECT 'namespace-urn' as 'xmlns:namespace', 
     1 as 'namespace:a' 
    FOR XML RAW
    

    Результат этого запроса будет таким:

    <row xmlns:namespace="namespace-urn" namespace:a="1"/>
    

    Обратите внимание, что для добавления пространств имен XML рекомендуется использовать предложение WITH XMLNAMESPACES.

  • В запросе SELECT приведение любого столбца к большому двоичному объекту (BLOB) делает этот столбец временной сущностью, которая теряет связанные с ней имя таблицы и имя столбца. Поэтому запросы в режиме AUTO будут возвращать ошибки, так как они не будут знать, куда поместить этот объект в иерархии XML. Например:

    CREATE TABLE MyTable (Col1 int PRIMARY KEY, Col2 binary)
    INSERT INTO MyTable VALUES (1, 0x7)
    

    Следующий запрос вернет ошибку из-за приведения к типу BLOB:

    SELECT Col1,
    CAST(Col2 as image) as Col2
    FROM MyTable
    FOR XML AUTO
    

    Решение этой проблемы заключается в добавлении параметра BINARY BASE64 к предложению FOR XML. Если удалено приведение типов, запрос вернет ожидаемый результат:

    SELECT Col1,
    Col2
    FROM MyTable
    FOR XML AUTO
    

    Результат:

    <MyTable Col1="1" Col2="dbobject/MyTable[@Col1='1']/@Col2" />
    
  • В SQL Server 2000 вывод запроса с FOR XML может содержать недопустимые символы XML. Например, шестнадцатеричное значение 7 используется как символ форматирования и обычно не отображается в выводе в виде текста. SQL Server 2005 преобразует такие символы в сущности, если они возвращаются запросами FOR XML, в которых отсутствует директива TYPE.
    Хотя синтаксические анализаторы, следующие стандарту XML 1.0, будут выводить ошибку независимо от того, преобразованы ли такие символы в сущности, это поведение более соответствует XML 1.1. Представление таких символов в виде сущностей также может оказаться более согласованным с будущими версиями стандарта XML. Кроме того, таким образом упрощается отладка, так как становится виден элемент кода, содержащий недопустимый символ.
    Пользователям инструментов XML не требуется делать никаких обновлений, так как анализатор XML в любом случае выдаст ошибку, встретив в потоке данных недопустимый символ. При использовании других инструментов это изменение может потребовать обновления программной логики для поиска таких символов в виде сущностей.

  • В SQL Server 2005 следующие пробельные символы в результатах запросов FOR XML преобразуются в различные сущности, чтобы сохранить их для обратных преобразований:

    • В содержимом и атрибутах элементов: hex(0D) (возврат каретки)
    • В содержимом атрибутов: hex(09) (табуляция), hex(0A) (перевод строки)

    Это может повлиять на приложение, если оно было спроектировано для обработки вывода SQL Server 2000, где эти символы были нормализованы. В выводе SQL Server 2005 этим символы сохраняются, а синтаксический анализатор их больше не нормализует.

См. также

Справочник

Создание XML с помощью предложения FOR XML

Другие ресурсы

SELECT (Transact-SQL)

Справка и поддержка

Получение помощи по SQL Server 2005