После выхода 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-сервис. Некоторые из перечисленных возможностей будут
здесь разобраны.
Начнем с того, что в дальнейшем в примерах
мы будем использовать управляемые (managed) библиотеки System.
Data (ADO .Net) и Microsoft.Data.SqlXml. Первая является
штатной функциональностью Visual Studio .Net, а вторая
устанавливается в составе SQLXML Web Release 2.0 и выше. Если
Вы экспериментируете с приводимыми здесь примерами,
пожалуйста, отметьте эти библиотеки в References для своего
проекта. Это вполне естественный выбор при использовании
.Net-средства разработки, который избавляет, например, от
возни с СОМ-маршалингом, при передаче массива интерфейсов
IDispatch (Variant) в параметры ADODB.Command.. Не следует,
впрочем, полагать, что с этого момента все рассматриваемые
задачи решаются только с помощью SQLXML Managed Classes.
Большинство разбираемых примеров вполне реализуются средствами
классического СОМовского ADO подобно тому, как показывалось в
п.п. 2 - 4. Однако с помощью новых технологий доступа к
данным, специально предназначенных для работы в .NET
Framework, этого можно достичь проще и быстрее. Скрипт 4
демонстрирует предыдущий пример (FOR XML-запрос на стороне
сервера), переписанный с ADODB на SqlXml.
using
System.Xml;
using
Microsoft.Data.SqlXml;
...
static void
Execute_FORXMLQuery_SQLXML()
{
SqlXmlCommand
cmd = new
SqlXmlCommand("Provider=SQLOLEDB;...");
cmd.CommandText
= "SELECT c.ContactName, c.ContactTitle, o.OrderDate FROM
Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID
WHERE c.ContactName = ? and year(o.OrderDate) = ? FOR XML
AUTO";
cmd.RootTag =
"Root";
cmd.CommandType
=
SqlXmlCommandType.Sql;
cmd.OutputEncoding
=
"UTF-8";
cmd.CreateParameter().Value
= "Maria
Larsson";
cmd.CreateParameter().Value
= 1997;
Stream str =
cmd.ExecuteStream();
XmlDocument
xml = new
XmlDocument();
xml.Load(str);
...
}
Скрипт 4
Логика примера не изменилась - выполняется 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).