Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Вопросы и ответы по MS SQL Server" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
MS SQL Server - дело тонкое...
Информационный Канал Subscribe.Ru |
#098<< #099 |
СОДЕРЖАНИЕ
В связи с переносом сервера на новый хостинг, наш сайт SQL.RU может быть временно недоступен вечером в пятницу и во все выходные. После переноса, некоторые разделы сайта будут недоступны в течение нескольких недель, которые потребуются для завершения переноса содержимого и скриптов на ASP.NET. Старый форум будет доступен в режиме read-only до окончания перехода на новый форум, который первоначально будет обладать меньшей функциональностью, но она будет увеличена в ближайшие недели с учетом ваших пожеланий. Мы с удовольствием ответим на ваши вопросы и прислушаемся к вашим пожеланиям, которые Вы можете оставить в нашем форуме: Переход SQL.RU под .NET Александр Сибилёв (admin@sql.ru)
XML в MS SQL Server 2000 и технологиях доступа к данным (продолжение) Автор: Алексей Шуленин
1. Введение 4. XML на стороне сервера. FOR XML Следующая ступень эволюции - ADO 2.6 и SQL Server 2000. В SQL Server 2000 в синтаксис Т-SQL был добавлен предикат FOR XML для оператора SELECT, что позволило получать XML-текст как результаты запроса на стороне сервера. Рассмотрим запрос SELECT c.ContactName, c.ContactTitle, o.OrderDate FROM Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID FOR XML AUTO. Вначале SQL Server традиционным способом выполняет ту часть запроса, которая находится до FOR XML. Затем к полученному множеству записей сервер применяет преобразование в XML. Если выполнить этот запрос из Query Analyzer, то видно, что содержимое XML-документа разбито по записям длиной 2033 символа Unicode одноколоночного recordset'а. Вообще говоря, это не есть ни recordset, ни XML. Его нельзя использовать как результат подзапросов, хранимых функций и всего остального, что предполагает дальнейшую обработку на SQL Server. Это нечто предназначено только для передачи клиенту, где из него уже происходит сборка полноценного документа. Таким образом, несмотря на то, что в отличие от Скриптов 1 и 2, в Скрипте 3 XML фактически получается на сервере, все XPath-, updategrams- и прочие запросы выполняются на клиенте, поскольку встроенный тип XML в настоящее время в SQL Server отсутствует.
Скрипт 3 выполняет тот же запрос, что и в предыдущих примерах, за исключением того, что я его слегка
разнообразил передачей параметров: он показывает список всех заказов, сделанных определенным клиентом
за определенный год. Результат заключается в скобки <Root> … </Root> для получения well-formed документа.
Вместо этого можно использовать cmd.Properties["xml root"].Value = "Root". XML возвращается на клиента в
объекте ADODB.Stream. Его можно сохранить сразу в файл - str.SaveToFile(f.FullName,
ADODB.SaveOptionsEnum.adSaveCreateOverWrite); , а можно передать как поток в документ типа
MSXML2.DOMDocument40Class. В любом случае понятно, что над результатами запроса можно вести
дальнейшую работу средствами DOM. Аналогично Скрипту 2 для работы с XML-документами здесь
используется библиотека СОМ, а не .NET, поскольку ADODB.Stream нельзя преобразовать к System.IO.Stream,
чтобы загрузить в System.Xml.XmlDocument. Передавать же, сохраняя в промежуточный файл, как делалось в
Скрипте 1, можно, но неизящно. Свойство Dialect класса ADODB.Command говорит провайдеру, какой тип
команды используется. Возможные значения приведены в Табл.1
Табл.1
Объекты типа Stream появились в ADO 2.5 для поддержки некоторых типов нереляционной информации. Вспомним,
что первоначальная спецификация OLE DB в 1996 г. описывала универсальный доступ в рамках прямоугольных
recordset'ов для обеспечения совместимости с ранними API, имевшими дело с реляционными данными
(ODBC, DB-Library, DAO). Однако несмотря на развитость аппарата реляционной алгебры далеко не все
источники удавалось свести к этому классу. Да и потом, иерархические базы данных все-таки предшествовали
реляционным, поскольку эта модель, видимо, более естественно отвечает образу мышления. Время шло,
диссонанс между объектно-ориентированной средой разработки и реляционной архитектурой хранения
(плоские таблицы, связанные отношениями) проявлялся все более отчетливо. В ADO 1.5 была сделана попытка
сгладить эту проблему с помощью провайдера MSDataShape. Спецификация OLE DB 1.5 предусматривала
новый тип полей - Chapter column. Предполагалось, что индивидуальные уровни иерархии можно представить
в виде отдельных rowset'ов, и chapter указывает для родительской записи множество ее детей в дочернем rowset'e.
Однако все это было хорошо в однородных иерархиях, когда дочерняя запись имеет тот же набор полей, что и
родительская. Например, очевидный негомогенный источник - файловая система - сюда уже не вписывается.
Чтобы уложить древовидную структуру в прямоугольную с минимальными переделками и потерями
производительности (скажем, не заводя для каждой записи число полей, соответствующее полному набору
всех возможных атрибутов узла в дереве, большая часть из которых будет, очевидно, пустовать) в ADO 2.5
были введены классы Record и Stream. Набор полей (атрибутов) записи (файла) может разниться не только с
родительской записью (папкой), но и меняться от записи к записи (например, в зависимости от типа файла).
Наименьший общий знаменатель полей, присущих всем записям, формировал колонки привычного Recordset.
Класс Stream соответствовал содержанию файла. Таким образом, появилась возможность получения результата
запроса в виде потoка, чем мы и воспользовались в Скрипте 3. XML естественным образом решает проблему
представления древовидных иерархий. Как и RDS, MSDataShape в настоящее время поддерживается по
соображениям совместимости, но развиваться в дальнейшем не будет.
После выхода SQL Server 2000 в августе 2000 г. дополнительная функциональность, в плане развития поддержки
XML, выпускалась в виде веб-релизов под названием SQLXML. SQLXML 1.0 содержал Updategrams, XML
Bulkload и усовершенствования в части производительности. В версии 2.0 ввели аннотированные XSD-схемы,
FOR XML на стороне клиента, SQLXMLOLEDB-провайдер и SQLXML Managed Classes (в плане интеграции с
ADO.Net). Наконец, веб-релиз версии 3.0, вышедший в марте 2002 г. и последний на момент подготовки
доклада, добавляет к этому поддержку SOAP, превращая SQL Server в Web-сервис. Некоторые из перечисленных
возможностей будут здесь разобраны.
Логика примера не изменилась - выполняется SQL-запрос, результаты получаются в виде XML и передаются
для последующей возможной работы в System.Xml.XmlDocument (аналог DOMDocument). Кроме того, для целей
демонстрации XML-поток сохраняется в файл, который затем открывается в браузере. Класс SqlXml.Command
для получения результатов в виде XML-потока имеет два метода: ExecuteStream() и ExecuteToStream(). Их
отличие состоит в том, что первый создает новый Stream, а второй пишет в уже существующий. Кроме того,
результаты запроса можно сразу получить как XmlReader (метод ExecuteXmlReader). В отличие от класса
XmlDocument (DOM) XmlReader является более легковесным, он не требует загрузки всего документа в память.
В терминологии баз данных его ближайшим аналогом будет forward-only read-only курсор. Свойство Dialect класса
Command в ADO соответствует свойству CommandType, а Output Encoding и XML Root перешли из расширенных
свойств в стандартные (OutputEncoding и RootTag).
6. FOR XML на стороне клиента.
Провайдер SQLXMLOLEDB является типичным сервисным провайдером, как уже упоминавшиеся ранее
MSDataShape и MSPersist, в том плане, что он получает данные от другого провайдера, а не непосредственно
из источника. SQLXMLOLEDB позволяет преобразовывать recordset в XML непосредственно на клиенте.
Таким образом, провайдер SQLOLEDB, стоящий между SQLXMLOLEDB и SQL Server, получает от сервера не
XML-поток, а обычный recordset и передает его SQLXMLOLEDB, который уже занимается превращением
реляционной информации в XML. Скрипт 5 демонстрирует FOR XML на стороне клиента.
При помощи SQL Profiler можно оттрассировать и сравнить запросы, которые в действительности обрабатываются
сервером при выполнении Скриптов 4 и 5.
Скрипт 4:
Скрипт 5:
В Скрипте 5 я слегка изменил текст запроса, чтобы показать использование GROUP BY (этот предикат не
разрешается в серверных FOR XML-запросах). Запрос считает количество заказов, сделанных каждым клиентом
за определенный период времени. Обратите внимание на отсутствие предиката FOR XML во втором случае.
Это значит, что преобразование recordset'a в XML действительно происходит в данном случае на клиенте.
поставить вместо SQL Server соответствующего OLE DB-провайдера. К сожалению, для этого придется
подождать следующего, 4-го, веб-релиза. Пока SQLXMLOLEDB умеет работать только с SQL Server 2000.
ПРОДОЛЖЕНИЕ СЛЕДУЕТ
ССЫЛКИ НА СТАТЬИ
Отечественные статьи
Проблема незапланированных запросов к базе данных
Новые технические статьи Microsoft
BUG:
SQL Server Books Online May be Misleading Regarding the Meaning of Max
Worker Threads (Q272428)
ФОРУМ SQL.RU
Самые популярные темы недели
База
данных - хранилище объектов.
Вопросы остались без ответа
DBCC
adduserobject
|
#098<< #099 |
|
http://subscribe.ru/
E-mail: ask@subscribe.ru |
Отписаться
Убрать рекламу |
В избранное | ||