Задачи

В DTS существует несколько типов задач. Одним из наиболее распространенных среди них является задача преобразования (Тransformation Тask). Она основана на интерфейсе IDTSDataPump и выполняет роль насоса по перекачке данных между двумя соединениями, т.е. переносит множество записей соединения-источника (таблица, SQL-запрос) в множество записей соединения-приемника. В качестве приемника может быть выбрана существующая таблица, либо создана новая, поля которой вообще говоря могут быть абсолютно неидентичны полям источника.

Рис. 2

Этап преобразования позволяет определить, как именно поля источника отображаются в поля назначения (см. рис.2), а также осуществить промежуточные преобразования в процессе переноса. Например, из рис.2 мы видим, что поля LastName и FirstName источника отображаются в одно поле EmployeeName приемника. Правило преобразования задается при помощи ActiveX-скрипта (см. рис.3).

Рис. 3

Функция Main описывает преобразование, выполняющееся для каждой записи источника. Встроенные объекты DTSSource и DTSDestination обозначают соответственно источник и приемник. Поля источника и приемника, участвующие в данной части преобразования, перечислены в текстовых окнах Source columns и Destination Columns. Процесс написания кода преобразования сделан максимально удобным. Например, двойной щелчок по полю EmployeeName приведет к появлению в окне Script выражения DTSDestination ("EmployeeName"). Аналогично появляется любая функция, допустимая в ActiveX Script, из числа перечисленных в списке Functions. Таким образом, мы видим, что поле EmployeeName в приемнике получается как конкатенация строковых полей FirstName и LastName источника, разделенных пробелом. Комбо Language позволяет выбрать язык программирования, на котором пишется преобразование. SQL Server 7.0 обеспечивает поддержку Scripting Host для VB Script, JavaScript и XML. Коды возврата функции преобразования позволяют управлять логикой выполнения преобразования в целом в случае возникновения исключительных ситуаций. Например, код возврата DTSTransformStat_SkipInsert означает не добавлять текущую обрабатываемую запись в приемник, DTSTransformStat_ExceptionRow прерывает обработку текущей записи, вызывает обработчик ошибок и записывает ее в файл исключений и т.д. Все коды возврата и генерируемые ими действия приводятся в документации на SQL Server (см. DTSTransformStatus).

В известном смысле Тransformation Тask можно рассматривать как частный случай задачи типа ActiveX Script, которая может содержать произвольный код на любом из упоминавшихся скриптовых языков с использованием встроенных объектов DTS, таких, как уже знакомые нам DTSSource, DTSDestination, DTSErrorRecords и т.д. Полный перечень этих объектов с описанием их методов и свойств содержится в документации на SQL Server (см. DTS Reference). Вот как мог бы выглядеть перенос данных "один в один" (поля приемника такие же, как поля источника) из одного формата в другой, оформленный в виде задачи ActiveX Script на JavaScript:

function main() {

for ( var i = 1; i <= DTSSource.Count ; i++ )

   DTSDestination(i) = toUpperCase(DTSSource(i));

   return(DTSTransformStat_OK);

}

В ходе переноса выполняется приведение строковых значений полей к верхнему регистру.

Задача типа SQL Script может содержать любую последовательность команд на языке Transact-SQL. Отметим, что при ее создании Вы можете воспользоваться графическим построителем SQL-запросов (см. рис.4), что значительно облегчает процесс написания кода запроса.

Рис. 4

Еще один тип задачи - это Data Driven Query Task (DDQ), название которого можно примерно перевести как определяемый данными запрос. Принцип ее действия легко понять также опираясь на рассмотренную нами выше Transformation Task. Последняя, как мы уже знаем, берет каждую запись из множества записей источника, делает (или не делает) над ее полями какое-либо преобразование и получившийся результат добавляет в назначение, т.е. выполняет INSERT. Иногда просто INSERT оказывается недостаточным. DDQ поддерживает 4 типа запроса (INSERT, UPDATE, DELETE и User Defined), которые оперируют над полями источника в зависимости от результата преобразования и которые прописываются в закладке Queries диалогового окна Data Driven Query Properties. Например,

INSERT INTO Categories(CategoryID, CategoryName, Description, Picture) VALUES (?,?,?,?)

UPDATE Categories SET Description = 'Mustard' WHERE CategoryID = (?) AND CategoryName = 'Produce'.

В качестве параметров запроса выступают поля приемника. Можно задать, какому полю какой параметр соответствует (см. рис.5). К кодам возврата DTSTransformStatus добавляются еще 4 кода: DTSTransformStat_InsertQuery, DTSTransformStat_UpdateQuery и т.д. Если функция Main в ActiveX-коде нашего преобразования, пример которого был рассмотрен выше, возвращает DTSTransformStat_InsertQuery, будет выполнен запрос на вставку, DTSTransformStat_UpdateQuery - на обновление и т.д.

Этот тип задачи используется в ситуациях, когда в зависимости от значений полей приемника наши действия над ними должны варьироваться.

В задачах типа Transformation и DDQ имеется еще одна полезная вещь под названием параметры поиска (Lookups). Представим себе ситуацию, когда в процессе переноса данных с одного соединения на другое нам нужно осуществить перекодировку данных, например, заменить фамилию сотрудника на его табельный номер, при этом таблица перекодировки может находиться вообще где-нибудь на третьем соединении. Это типичный пример, когда нам пригодится Lookup. Определением Lookup'a является запрос, который прописывается в диалоговом окне свойств задачи (закладка Advanced, кнопка Lookups). В нашем примере это будет, очевидно, такой запрос:

SELECT au_id FROM authors WHERE (au_lname = ?)

Рис. 5

Остается только выбрать соединение из числа определенных внутри данного пакета (может быть отличным от источника и назначения), на котором будет выполняться этот запрос, и как-нибудь обозвать параметр поиска, например, MyLookup. Теперь в коде преобразования можем написать:

DTSDestination("au_id")= DTSLookups("МyLookup").Execute(DTSSource("au_lname").Value)

При этом будет выполнен приведенный выше запрос, служащий определением параметра поиска, которому на входе будет передано текущее значение поля au_lname. Результат (значение au_id) будет присвоен в соответствующее поле приемника. Что затем произойдет с полями приемника - зависит от типа задачи. В случае Transformation они однозначно будут добавлены в назначение, в случае DDQ - зависит от кода возврата, т.е. от нас.

Оставшиеся типы задач достаточно тривиальны. Задача массированной вставки (Bulk Insert Task) есть частный случай SQL Task и представляет собой аналог одноименной команды Transact-SQL, обеспечивающей копирование данных из текстового файла в SQL Server. Отметим, что она доставляет максимальное быстродействие, но не позволяет применить никаких преобразований над данными в процессе переноса и требует от провайдера назначения поддержки интерфейса IRowsetFastLoad. Перенос объектов (Transfer SQL Server Objects) между двумя SQL Server-соединениями нами уже обсуждался. Напомним, что этот тип задачи переносит индексы, хранимые процедуры, представления, пользователей и пр. и основан на интерфейсах SQL-DMO. Execute Process Task выполняет команду операционной системы. Send Mail предназначен для отправки электронной почты и для своей работы требует, чтобы на сервере был установлен MAPI-клиент с действительным профилем пользователя.

Рис. 6

Понятно, что сколько бы типов задач ни было предусмотрено в пакете, в жизни всегда найдется место подвигу, т.е. встретится ситуация, когда этого будет недостаточно. Поэтому в пакет введено понятие базового интерфейса IDTSCustomTask, от которого, кстати, произведены все рассмотренные нами типы задач. При написании собственного типа задач Вы поступаете точно так же, наследуя данный интерфейс, после чего спокойно совершаете свой подвиг, реализуя коллекцию свойств, метод Execute и т.д. Кстати, чтобы в графическом интерфейсе DTS Designer было удобнее работать с созданным Вами типом задач, стоит обратить внимание на DTSCustomTaskUI.

Назад | Содержание | Вперед