MS SQL Server + FireBird = ДружбаИсточник: delphikingdom Александр Чмиль
Автор: Александр Чмиль, Королевство Delphi Недавно столкнулся с проблемой, когда данные из базы данных FireBird (F) нужно было импортировать в базу данных MS SQL Server 2000 (S). Первой мыслью было написать клиента, который бы подключался одновременно к двум БД и в цикле переносил данные из всех таблиц одной базы в другую. Данный подход мне сразу не понравился тем, что пришлось бы писать на Delphi отдельную процедуру импорта данных под каждую таблицу БД - структура и типы данных у них ведь разные. Кроме того, типы данных у этих БД несколько "не стыкуются", так что пришлось бы учитывать и эту особенность при переносе данных. За советом я обратился к специалистам на Круглом столе Королевства Delphi - вопрос № 71949. Достопочтенный Green в первом же ответе направил меня совершенно в другом направлении: не клиента писать, а подружить эти две СУБД. Полученный результат настолько меня впечатлил, что я решил написать данную статью. Итак, для того, чтобы иметь возможность делать запросы из (S) к (F), в первую очередь необходимо установить OLE-провайдер, обеспечивающего связь с БД (F). Поиск в Интернете привел на сайт http://www.ibprovider.com, с которого можно скачать бесплатную версию IBProvider. Функционала данной версии вполне достаточно для выполнения задуманного, хотя никто не мешает приобрести платную версию, но нужно ли это в рамках данной задачи? Следующим шагом будет регистрация IBProvider в системе. Копируем файлы _IBProvider_v3_free_i.dll и cc3250mt.dll в системную папку Windows (например, в c:\windows\system32) и в командной строке выполняем команду:
В результате в списке провайдеров появится LCPI.IBProvider.3.Free. Хочу заметить, что для "дружбы" (S) с (F) в системе должна быть запущена служба MSDTC (Distributed Transaction Coordinator или Координатор Распределенных Транзакций). В моем случае данная служба была отключена и в упорно не желала запускаться (MS Windows 2000). Поиск в Интернете привел к следующему трюку в командной строке:
При наличии прав администратора в списке служб находим "Координатор распределенных транзакций" и устанавливаем тип запуска "авто". Все. Теперь мы можем работать с БД (F) как из скрипта MS SQL Server, так и через TADOConnection в Delphi, указав в качестве провайдера LCPI.IBProvider.3.Free. Вот пример содержимого строки ADOConnection.ConnectionString:
Вернусь к своей задаче - импорт данных в БД MS SQL Server из БД FireBird. Создаем БД (S) по структуре идентичную БД (F). Из-за различий в типах данных этих двух СУБД, в БД (S) создаем столбцы в соответствии с таблицей приведения типов:
Не буду расписывать все соответствия. Их Вы можете определить экспериментально или найти информацию в Интернете. Перейдем к самому интересному - к "дружбе народов" : Для получения набора данных из внешней БД, в СУБД (S) имеется функция OpenRowSet, синтаксис которой выглядит так:
Описание функции Вы можете найти в Transact-SQL Reference. В нашем случае эта функция используется с таким набором параметров:
В качестве первого параметра указывается имя провайдера (LCPI.IBProvider.3.Free), в качестве второго - строка соединения с БД FireBird, третьего - запрос на выборку данных (select * from TableName). Для импортирования данных на (S) создаем две ХП:
Выполняем процедуру ImportFBData, которая поочередно вызывает процедуру ImportFBTable, передавая ей в качестве параметра имя импортируемой таблицы (естественно, имена таблиц в (F) и (S) должны быть одинаковыми). Процедура ImportFBTable очищает данные в таблице на (S), получает набор данных из таблицы на (F) и вносит их в таблицу на (S). Конечно, при желании можно "заставить" процедуру не удалять данные, а обновлять, но предоставляю Вам самим создать сие действо - в рамках моей задачи это было не обязательно, так как я не использовал в таблицах на (S) внешние индексы. Вот, собственно, и вся статья. Возможно, Вас не устроит стиль изложения или Вы заметите некоторые неточности или недомолвки? Тогда предлагаю обсудить это на соответствующей странице. В заключении хотел сказать, что таким образом можно "подружить" MS SQL Server и с другими БД при наличии соответствующего OLE-провайдера. Например, вот тут вопрос № 71737 рассказывается, как можно получить данные с листа MS Excel. Также хочу выразить огромную благодарность г-ну Александру Зеленову (aka Green), вовремя направившего меня "на путь истинный" и вдохновившего к написанию данной статьи. |