Форматирование XML-кода на клиенте и на сервере (SQLXML 4.0)
В этом разделе описывается основные различия между форматированием XML-кода на стороне клиента и на стороне сервера.
Запросы к нескольким наборам строк не поддерживаются в форматировании на стороне клиента
Запросы, создающие несколько наборов строк, не поддерживаются при использовании форматирования XML-кода на стороне клиента. Например, предположим, что имеется виртуальный каталог, в котором указано форматирование на стороне клиента. Рассмотрим этот образец шаблона, который имеет две инструкции в блоке <sql:query>:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:query> SELECT FirstName FROM Person.Contact FOR XML Nested; SELECT LastName FROM Person.Contact FOR XML Nested </sql:query></ROOT>
При выполнении данного шаблона в коде приложения возвращается ошибка, так как форматирование XML-кода на стороне клиента не поддерживает форматирование нескольких наборов строк. При указании запросов в двух отдельных блоках <sql:query> получаются желаемые результаты.
Различное соответствие типа timestamp в клиенте и форматирование на стороне сервера
При форматировании XML-кода на стороне сервера столбец базы данных типа timestamp соответствует типу XDR «i8» (если параметр XMLDATA указан в запросе).
При форматировании XML-кода на стороне клиента столбец базы данных типа timestamp соответствует либо типу XDR uri, либо bin.base64 (в зависимости от того, указан ли в запросе параметр «binary base64»). Тип XDR bin.base64 удобен при использовании диаграмм обновления и массовой загрузки, так как он преобразуется в тип SQL Servertimestamp. Таким образом, операции вставки, обновления или удаления выполняются успешно.
При форматировании на стороне сервера используются глубокие типы VARIANT
При форматировании XML-кода на стороне сервера используются глубокие типы VARIANT. При форматировании XML-кода на стороне клиента типы VARIANT преобразуются в строку в Юникоде, а вложенные типы VARIANT не используются.
Режим NESTED и режим AUTO
Режим NESTED предложения FOR XML на стороне клиента аналогичен режиму AUTO предложения FOR XML на стороне сервера, за исключением следующих моментов.
При запросе представлений с помощью режима AUTO на стороне сервера, имя представления возвращается в виде имени элемента в результирующем XML-коде.
Например, предположим, что следующее представление создается для таблицы Person.Contact в базе данных AdventureWorks:
CREATE VIEW ContactView AS (SELECT ContactID as CID, FirstName as FName, LastName as LName FROM Person.Contact)
Следующий шаблон указывает запрос к представлению ContactView, а также форматирование XML-кода на стороне сервера:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:query client-side-xml="0"> SELECT * FROM ContactView FOR XML AUTO </sql:query></ROOT>
После выполнения шаблона возвращается следующий XML-код. (Показываются только частичные результаты). Обратите внимание, что имена элементов - это имена представлений, к которым выполняется запрос.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <ContactView CID="1" FName="Gustavo" LName="Achong" /> <ContactView CID="2" FName="Catherine" LName="Abel" /> ...</ROOT>
При указании форматирования XML-кода на стороне сервера с помощью режима NESTED, имя(имена) базовой таблицы возвращаются в виде имени(имен) элемента в результирующем XML-коде. Например, следующий измененный шаблон выполняет ту же инструкцию SELECT, но теперь форматирование XML-кода выполняется на стороне клиента (то есть, client-side-xml устанавливается в значение TRUE в шаблоне):
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:query client-side-xml="1"> SELECT * FROM ContactView FOR XML NESTED </sql:query></ROOT>
В результате выполнения этого шаблона создается следующий XML-код. Обратите внимание, что именем элемента в этом случае является имя базовой таблицы.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <Person.Contact CID="1" FName="Gustavo" LName="Achong" /> <Person.Contact CID="2" FName="Catherine" LName="Abel" /> ...</ROOT>
При использовании режима AUTO предложения FOR XML на стороне сервера, псевдонимы таблиц, указанные в запросе, возвращаются в виде имен элементов в результирующем XML-коде.
Например, рассмотрим следующий шаблон.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:query client-side-xml="0"> SELECT FirstName as fname, LastName as lname FROM Person.Contact C FOR XML AUTO </sql:query></ROOT>
В результате выполнения этого шаблона создается следующий XML-код.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <C fname="Gustavo" lname="Achong" /> <C fname="Catherine" lname="Abel" /> ...</ROOT>
При использовании режима NESTED предложения FOR XML на стороне клиента, имена таблиц возвращаются в виде имен элементов в результирующем XML-коде. (Псевдонимы таблиц, указанные в запросе, не используются). Например, рассмотрим следующий шаблон.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:query client-side-xml="1"> SELECT FirstName as fname, LastName as lname FROM Person.Contact C FOR XML NESTED </sql:query></ROOT>
В результате выполнения этого шаблона создается следующий XML-код.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <Person.Contact fname="Gustavo" lname="Achong" /> <Person.Contact fname="Catherine" lname="Abel" /> ...</ROOT>
При наличии запроса, возвращающего столбцы в виде запросов объектов базы данных, использовать псевдонимы для этих столбцов нельзя.
Например, рассмотрим следующий шаблон, выполняющий запрос, который возвращает идентификатор и фото сотрудника.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"><sql:query client-side-xml="1"> SELECT ProductPhotoID, LargePhoto as P FROM Production.ProductPhoto WHERE ProductPhotoID=5 FOR XML NESTED, elements</sql:query></ROOT>
Выполнение этого шаблона возвращает столбец Photo в виде запроса объекта базы данных. В запросе объекта базы данных @P ссылается на имя несуществующего столбца.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <Production.ProductPhoto> <ProductPhotoID>5</ProductPhotoID> <LargePhoto>dbobject/Production.ProductPhoto[@ProductPhotoID='5']/@P</LargePhoto> </Production.ProductPhoto></ROOT>
Если на сервере выполнено форматирование XML-кода (client-side-xml="0"), то можно использовать псевдоним для столбцов, возвращающих запросы объектов базы данных, в которых возвращаются действительные имена таблиц и столбцов (даже при наличии указанных псевдонимов). Например, следующий шаблон выполняет запрос, и на сервере производится форматирование XML-кода (параметр client-side-xml не указывается, а параметр Run On Client не выбирается для виртуального корневого каталога). Запрос также указывает режим AUTO (а не режим NESTED на стороне клиента).
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"><sql:query SELECT ProductPhotoID, LargePhoto as P FROM Production.ProductPhoto WHERE ProductPhotoID=5 FOR XML AUTO, elements</sql:query></ROOT>
При выполнении шаблона возвращается следующий XML-документ (обратите внимание, что псевдонимы не используются в запросе объектов базы данных для столбца LargePhoto):
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <Production.ProductPhoto> <ProductPhotoID>5</ProductPhotoID> <LargePhoto>dbobject/Production.ProductPhoto[@ProductPhotoID='5']/@LargePhoto</LargePhoto> </Production.ProductPhoto></ROOT>
XPath на стороне клиента и на стороне сервера
XPath на стороне клиента и на стороне сервера работают аналогично, за исключением следующих моментов.
Преобразования данных, применяемые при использовании запросов XPath на стороне клиента, отличаются от применяемых при использовании запросов XPath на стороне сервера. XPath на стороне клиента использует CAST вместо CONVERT mode 126.
При указании в шаблоне client-side-xml="0" (FALSE) запрашивается форматирование XML-кода на стороне сервера. Таким образом, нельзя указать FOR XML NESTED, так как сервер не распознает параметр NESTED. Это приводит к ошибке. Необходимо использовать режимы AUTO, RAW или EXPLICIT, которые сервер распознает.
При указании в шаблоне client-side-xml="1" (TRUE) запрашивается форматирование XML-кода на стороне клиента. В этом случае можно указать FOR XML NESTED. При указании FOR XML AUTO, форматирование XML-кода происходит на стороне сервера, хотя client-side-xml="1" указывается в шаблоне.