Работает он так: сначала находится запись, однозначно
идентифицируемая в разделе before (ее мы вставили в предыдущем примере). Этой записи, с помощью атрибута id, присваивается идентификатор. Зачем он нужен? Так как в
разделе after мы указали две записи, то возникает неоднозначность: одну из них
нужно использовать для вставки, а другую для обновления. Чтобы эту
неоднозначность разрешить, в разделе after присутствует ссылка на найденную в
разделе before запись посредством атрибута id. В результате выполнения шаблона
будут исправлены имя и фамилия в записи с идентификатором 123-15-3452, а также
добавлена новая запись.
Удаление
Это совсем тривиальная задача, главное помнить, что в
разделе before запись должна однозначно определяться.
В этом примере будет удалена запись с идентификатором
123-15-3453.
ПРИМЕЧАНИЕ
Атрибуты «Имя» и «Фамилия» приведены
здесь для того, чтобы вам проще было понять, какая строка удаляется. Так как
идентификатор уникально определяет запись, их можно было не указывать.
Более подробную информацию об апдейтаграммах с
примерами можно найти в MSDN или в [10].
XML Bulk Load
Предположим, у вас имеется XML-документ, содержимое
которого нужно «залить» в базу. Методов решения проблемы, как всегда, очень
много, и вся сложность состоит в выборе наиболее подходящего. Вы можете
загрузить документ в DOMDocument и в цикле, выбирая значения элементов и
атрибутов, производить добавление данных с помощью инструкции SQL. Если вы не
знакомы с объектной моделью DOM, то можете написать свой парсер. Такое лобовое
решение обычно принимают самые отважные и «крутые» программисты, которые не
боятся трудностей написания нового парсера, изучения SQL и начальства. Что ж, лично я (хотя начальства не особо боюсь) к такой категории себя отнести не
могу. Мне нужно решение, которое опирается на уже существующие возможности и
технологии. Второе, что приходит в голову – передать XML-документ в хранимую
процедуру и с помощью OPENXML «залить» данные в таблицу. Решение здравое и
наиболее эффективное в большинстве случаев. Но что делать, если у вас имеется
большой документ? Конечно, его можно все так же передавать в хранимую процедуру
в параметре text или ntext и также разбирать с помощью OPENXML. Но все дело в
том, что OPENXML использует DOM, а обработка больших документов таким способом
имеет кучу недостатков. Мало того, что расходуется большое количество
драгоценных системных ресурсов, это еще и медленно! Для больших документов
идеальным вариантом является XML Bulk Load.
XML Bulk Load – это обычный COM-сервер, размещенный в
DLL, и использующий для анализа XML-документа SAX (Simple API for XML).
Благодаря этому он обрабатывает документ по частям, намного менее ресурсоемок и
более быстр. Для обновления данных XML Bulk Load должен знать, какие XML-узлы
соотносятся с полями в таблицах, и каков их тип. Для этого он использует все те
же аннотированные схемы, которые могут быть написаны на XDR или XSD.
Семантика объекта XML Bulk Load не может показаться
сложной – объект содержит всего один метод и несколько свойств. Рассмотрим
наиболее используемые свойства:
ConnectionString – строка соединения с базой данных
(формат SQLOLEDB).
ConnectionCommand – позволяет использовать уже
существующий объект ADODB.Connection.
BulkLoad – если установлено в true, кроме генерации
схемы (таблиц) происходит также закачка данных. Если установлен в false –
создаются только таблицы (см. свойство SchemaGen). По умолчанию – true.
ErrorLogFile – позволяет указать файл, в который будут
записываться сообщения об ошибках.
Transaction – если установлено в true, все операции
XML Bulk Load выполняются в контексте одной транзакции. По умолчанию – false.
TempFilePath – директория, в которой будет создан файл
лога транзакции. Настоятельно рекомендую устанавливать его самостоятельно, так
как по-другому у меня просто не получалось. Свойство имеет значение, только
если Transaction установлено в true. По умолчанию создает файл в папке %temp%.
SchemaGen – если установлено в true, создаются
указанные в аннотированной схеме таблицы. Если таблицы уже существуют, используется свойство SGDropTables. По умолчанию – false.
SGDropTables – если установлено в true, существующие в
базе таблицы удаляются перед закачкой. Для добавления данных к уже
существующим, оставьте это свойство равным false (по умолчанию).
KeepIdentity – если установлено в true, то значения
для поля типа identity выбираются из XML-документа, если false – SQL Server сам
выполняет обновление данного поля. По умолчанию – false.
Другие свойства можно найти в документации, все они
аналогичны настройкам утилиты bcp (bulk copy program – утилита командной
строки, поставляемая с SQL Server, которая позволяет загружать/выгружать данные
в/из текстового файла) и оператора BULK LOAD. Перейдем к примерам.
Создание новой таблицы и загрузка данных
В разделе "Апдейтаграммы", в примере
"Добавление данных" мы создали простую таблицу из одного поля и
добавили в нее значение. Вот как это можно сделать с помощью XML Bulk Load.