Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Сокровищница
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  04:27[Войти] | [Зарегистрироваться]

MS SQL Server + FireBird = Дружба

Александр Чмиль
дата публикации 15-09-2009 13:15

MS SQL Server + FireBird = Дружба

Недавно столкнулся с проблемой, когда данные из базы данных 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) и в командной строке выполняем команду:

regsvr32 _IBProvider_v3_free_i.dll

В результате в списке провайдеров появится LCPI.IBProvider.3.Free.

Хочу заметить, что для "дружбы" (S) с (F) в системе должна быть запущена служба MSDTC (Distributed Transaction Coordinator или Координатор Распределенных Транзакций). В моем случае данная служба была отключена и в упорно не желала запускаться (MS Windows 2000). Поиск в Интернете привел к следующему трюку в командной строке:

net stop msdtc (останавливаем службу msdtc)
net start msdtc (запускаем службу)

При наличии прав администратора в списке служб находим "Координатор распределенных транзакций" и устанавливаем тип запуска "авто".

Все. Теперь мы можем работать с БД (F) как из скрипта MS SQL Server, так и через TADOConnection в Delphi, указав в качестве провайдера LCPI.IBProvider.3.Free. Вот пример содержимого строки ADOConnection.ConnectionString:

Provider=LCPI.IBProvider.3.Free;Password=пароль_к_БД;Persist Security Info=True;User ID=логин_к_БД;
Location=D:\Projects\db\DB.FDB;ctype=ASCII;dialect=3;auto_commit=False;
support_odbc_query=False;unicode_mode=False;unicode_stmt=False;dbclient_library=gds32.dll;
dbclient_type=fb

Вернусь к своей задаче — импорт данных в БД MS SQL Server из БД FireBird. Создаем БД (S) по структуре идентичную БД (F). Из-за различий в типах данных этих двух СУБД, в БД (S) создаем столбцы в соответствии с таблицей приведения типов:

Типы данных (F)Типы данных (S)
timestampdatetime
varcharnvarchar
floatfloat или money
smallint (в роли boolean)bit
blobimage

Не буду расписывать все соответствия. Их Вы можете определить экспериментально или найти информацию в Интернете.

Перейдем к самому интересному — к "дружбе народов" :

Для получения набора данных из внешней БД, в СУБД (S) имеется функция OpenRowSet, синтаксис которой выглядит так:

OpenRowSet ( 'provider_name' 
    , { 'datasource' ; 'user_id' ; 'password' 
        | 'provider_string' } 
    , { [ catalog. ] [ schema. ] object 
        | 'query' } 
    ) 

Описание функции Вы можете найти в Transact-SQL Reference. В нашем случае эта функция используется с таким набором параметров:

OpenRowSet ('provider_name', 'provider_string', 'query')

В качестве первого параметра указывается имя провайдера (LCPI.IBProvider.3.Free), в качестве второго — строка соединения с БД FireBird, третьего — запрос на выборку данных (select * from TableName).

Для импортирования данных на (S) создаем две ХП:

CREATE PROCEDURE ImportFBTable
 @Table nvarchar(30)
AS
BEGIN
 exec('delete from '+@Table)
 exec('insert into '+@Table+' select * from OpenRowSet(''LCPI.IBProvider.3.Free'','''+
  'Password=пароль_FB;Persist Security Info=True;User ID=логин_FB;'+
  'Location=_путь_к_файлу_БД_FB;ctype=ASCII;dialect=3;'+
  'auto_commit=True;support_odbc_query=False;unicode_mode=False;'+
  'unicode_stmt=False;dbclient_library=gds32.dll;dbclient_type=fb'+
  ''',''select * from '+@Table+''')')
END

CREATE PROCEDURE ImportFBData
AS
BEGIN
 exec ImportFBTable 'Таблица_1'
 exec ImportFBTable 'Таблица_2'
 exec ImportFBTable 'Таблица_3'
 ...
 exec ImportFBTable 'Таблица_N'
END

Выполняем процедуру ImportFBData, которая поочередно вызывает процедуру ImportFBTable, передавая ей в качестве параметра имя импортируемой таблицы (естественно, имена таблиц в (F) и (S) должны быть одинаковыми). Процедура ImportFBTable очищает данные в таблице на (S), получает набор данных из таблицы на (F) и вносит их в таблицу на (S). Конечно, при желании можно "заставить" процедуру не удалять данные, а обновлять, но предоставляю Вам самим создать сие действо — в рамках моей задачи это было не обязательно, так как я не использовал в таблицах на (S) внешние индексы.

Вот, собственно, и вся статья. Возможно, Вас не устроит стиль изложения или Вы заметите некоторые неточности или недомолвки? Тогда предлагаю обсудить это на соответствующей странице.

В заключении хотел сказать, что таким образом можно "подружить" MS SQL Server и с другими БД при наличии соответствующего OLE-провайдера. Например, вот тут вопрос № 71737 рассказывается, как можно получить данные с листа MS Excel.

Также хочу выразить огромную благодарность г-ну Александру Зеленову (aka Green), вовремя направившего меня "на путь истинный" и вдохновившего к написанию данной статьи.




Смотрите также материалы по темам:
[MS SQL Server] [Гетерогенные запросы] [FireBird & Yafill]

 Обсуждение материала [ 22-06-2010 00:21 ] 5 сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования