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

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

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


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

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

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

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

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

 
   
С Л С

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

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

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

Квинтана

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

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

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

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

 
  
АРХИВЫ

 
 

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

23-07-2009 01:58
Всем доброго дня.

Совет ваш нужен. На удаленном объекте есть база данных Firebird. В офисе развернут SQL Server 2000, на котором создал базу данных, по структуре практически совпадающую с firebird-овской (вместо timestamp - datetime, varchar - nvarchar, float - money, smallint - bit, blob - image). Так вот, мне необходимо вносить изменения в БД офиса из БД объекта, то есть иметь в офисе актуальные данные.
Написал небольшой проект, периодически производящий бэкап, архивацию и разбивку на небольшие файлы базы на объекте (связь неустойчивая, поэтому проще качать данные небольшими порциями). В офисе файлы склеиваются, восстанавливается исходная БД firebird. Это все уже реализовано.
И вот тут дилемма возникла. Как бы мне унифицировать процедуру чтения данных из таблиц firebird и записи в таблицы sql server? Как-то некрасиво вручную перебирать все таблицы и имена полей.

Использую компоненты: TZConnection, TZQuery, TADOConnection, TADOQuery.
Использование SQL Server'a обязательно - пожелание админов.

Кто что подскажет? Заранее спасибо.

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

14-05-2010 00:11 | Сообщение от автора вопроса
2 simon.kms: Неа, не получится. По крайней мере мне так думается. Хотя знатокам FB видней.

У меня другая проблема возникла: не получается импортировать данные, если в поле типа BLOB имеются данные, отличные от NULL. Так что в своей статье я был неправ касательно дружбы BLOB и IMAGE. Что только не пробовал - не получается. А в BLOB записываются snapshot'ы с камеры наблюдения AXIS в момент, когда на весы КТП что-то заехало (превышен некий порог веса). Затем в офисе можно визуально удостовериться, что въезжала/выезжала именно та машина, которая указана в накладной или никакого левака со склада вывезено не было.
На данный момент между удаленным объектом и офисом установили стабильную высокоскоростную связь, так что данные теперь сохраняю не на объекте в FB с последующим импортом на сервер, а пишу напрямую на сервер офиса (MSSQL).

13-04-2010 23:36 | Вопрос к автору: запрос дополнительной информации
В-общем, довольно подробно описан механизм переноса информацию в одну сторону: из FB в MSSQL. Сразу же подумалось: а в обратную сторону переливать данные получиться? Могу ли я с помощью описанного варианта увидеть, к примеру, результаты запроса из FB к таблицам в MSSQL?

24-07-2009 02:44 | Сообщение от автора вопроса
Думаю, это не твой случай
Именно так.
Для достоверности результата перезагрузил компьютер, запустил процедуру - 5 секунд. Еще раз огромное спасибо!

24-07-2009 02:37
Время составило 2 секунды! Это что такое может быть: данные где-то кешируются или ExecProc не ждет окончания выполнения процедуры? Или может так и должно быть?

ExecProc не ждет окончания процедуры только при асинхронном выполнении. Думаю, это не твой случай. А 2 секунды для импорта небольших таблиц - нормальный результат.

24-07-2009 02:31 | Сообщение от автора вопроса
Пошел еще дальше:

procedure TForm1.sButton1Click(Sender: TObject);
var t1,t2:TDateTime; sec:integer;
begin
try
  ADOConnection2.Connected:=true;
  t1:=Now;
  ADOStoredProc2.ProcedureName:='ImportFBData';
  ADOStoredProc2.Prepared:=true;
  ADOStoredProc2.ExecProc;
  t2:=Now;
  sec:=SecondsBetween(t2,t1);
  ShowMessage('Время операции: '+inttostr(sec)+' сек.')
finally
  ADOConnection2.Connected:=false;
end
end;

Время составило 2 секунды! Это что такое может быть: данные где-то кешируются или ExecProc не ждет окончания выполнения процедуры?
Или может так и должно быть? Если так, то УРА! Green, Noskov огромное спасибо.
Green, ты даже не представляешь как я тебе благодарен! Мало того, что сэкономил мне кучу времени, так еще и ткнул меня носом и помог разобраться в новом для меня направлении. Еще раз спасибо!

24-07-2009 02:15
Noskov, спасибо. Попробую.
Кстати, интересная особенность! Я запускал процедуру ImportFBData прямо в редакторе процедуры (EMS SQL Manager 2005), в результате чего время составило около 6 минут. Попробовал выполнить команду exec ImportFBData в окне SQL Script - отработало за ... 9 секунд %(

Это как так?

24-07-2009 01:59
Несколько ускорить процесс должна замена DELETE FROM на TRUNCATE TABLE
А секцию SET в update-запросе можно и динамически сформировать:

declare @S nvarchar(max)
select @s = ''
select @s = @s + [name] + '=' + [name] + ','
from sys.columns
where [object_id] = object_id('TableName') and [name] <> 'id'
select @s=left(@s, len(@s) - 1)

select @s



24-07-2009 01:42
Изучил описание UPDATE - вроде как все столбцы скопом без указания имени обновить нельзя.

Да, нужно указывать все столбцы.

24-07-2009 01:41
Может подскажете, как бы мне оптимизировать мои процедуры? Самая объемная таблица - RECORD, в ней около 500 записей. Так вот, время на импорт всей БД составило около 6 минут :| Как-то чересчур уж многовато.

6 минут на 500 записей действительно многовато. 6 секунд - нормально :)
Сначала надо разобраться в чем тормоза - во вставке или в чтении из FB. Подозреваю, что проблема в работе через OpenRowSet и через провайдера FB. Тогда ускорить вряд ли получится. Я работал через OpenRowSet, но с Акцессом, а это все-таки продукт Майкрософта. И запуска DTS он не требовал. Попробуй просто выполнить SELECT без вставки - сколько времени он будет выполняться? И посмотри - сильно ли отличается время SELECT'а для разных таблиц?

24-07-2009 01:09
Кстати, еще раз просмотрел твой пост от 23-07-2009 07:29
Идею ты предложил хорошую, да вот тут UPDATE СтараяТаблица SET ... FROM НоваяТаблица WHERE СтараяТаблица.ID = НоваяТаблица.ID мне придется перебирать все имена столбцов. Изучил описание UPDATE - вроде как все столбцы скопом без указания имени обновить нельзя. Может есть еще какой способ?

24-07-2009 00:51 | Сообщение от автора вопроса
Green. У меня еще вопрос. Я в SQL не особо силён, изучаю на практике. Может подскажете, как бы мне оптимизировать мои процедуры? Самая объемная таблица - RECORD, в ней около 500 записей. Так вот, время на импорт всей БД составило около 6 минут :| Как-то чересчур уж многовато.

23-07-2009 08:58
Я пошел по более простому пути. Структура БД не сложная, особо большие скорости не нужны, поэтому от внешних ключей отказался.
Вот, что у меня получилось:

CREATE PROCEDURE ImportFBData
AS
BEGIN
declare @s1 varchar(30)
declare @s2 varchar(255)
set @s1='LCPI.IBProvider.3.Free'
set @s2='Password=***;Persist Security Info=True;User ID=***;'+
          'Location=D:\Projects\AccessScale\db\SCALE.FDB;ctype=ASCII;dialect=3;'+
          'auto_commit=True;support_odbc_query=False;unicode_mode=False;'+
          'unicode_stmt=False;dbclient_library=gds32.dll;dbclient_type=fb'

exec ImportFBTable @s1, @s2, 'CARS'
exec ImportFBTable @s1, @s2, 'CONTRAGENTS'
exec ImportFBTable @s1, @s2, 'DEPARTMENT'
exec ImportFBTable @s1, @s2, 'DISTANCES'
exec ImportFBTable @s1, @s2, 'EVENTS'
exec ImportFBTable @s1, @s2, 'FIOS'
exec ImportFBTable @s1, @s2, 'GOODS'
exec ImportFBTable @s1, @s2, 'INVOICES'
exec ImportFBTable @s1, @s2, 'PERCENTS'
exec ImportFBTable @s1, @s2, 'PSW'
exec ImportFBTable @s1, @s2, 'RECORD'
exec ImportFBTable @s1, @s2, 'SYSACTIONS'
exec ImportFBTable @s1, @s2, 'TAG'
exec ImportFBTable @s1, @s2, 'USERS'
exec ImportFBTable @s1, @s2, 'WAYPOINTS'
exec ImportFBTable @s1, @s2, 'WESLOGO'

END

CREATE PROCEDURE ImportFBTable
@Prov nvarchar(30), @ConStr nvarchar(255), @Table nvarchar(30)
AS
BEGIN
exec('delete from '+@Table)
exec('insert into '+@Table+' select * from OpenRowSet('''+@Prov+''','''+@ConStr+''',''select * from '+@Table+''')')
END


23-07-2009 07:29
Все просто. Сначала delete from Table, а затем insert бла-бла-бла )))

Ну, это просто, если в БД нет внешних ключей.
А если есть, то тоже не очень сложно:

UPDATE СтараяТаблица SET ... FROM НоваяТаблица WHERE СтараяТаблица.ID = НоваяТаблица.ID
INSERT INTO СтараяТаблица SELECT НоваяТаблица.* FROM НоваяТаблица LEFT JOIN СтараяТаблица ON НоваяТаблица.ID = СтараяТаблица.ID WHERE СтараяТаблица.ID IS NULL


23-07-2009 06:39
Тю, блин. Все просто. Сначала delete from Table, а затем insert бла-бла-бла )))

23-07-2009 06:37
Надеюсь, не нужно говорить, что вставку теперь можно сделать одной командой?
В том то и дело, что не совсем все так просто. Мне нужно не только вставлять данные, но и обновлять существующие... Вот, копаю sql.ru в поиске решения. А может есть идея?

23-07-2009 06:33
И фсе запустилось :)
Открыть FB под MSSQL?! Даже не верится, что такая фантастика возможна на практике :)

Надеюсь, не нужно говорить, что вставку теперь можно сделать одной командой?
INSERT INTO ТаблицаMSSQL SELECT * FROM OpenRowSet(...)

23-07-2009 05:53
Эх, Майкрософт. Так замутили устранение ошибки.
Оказалось все просто: пуск, выполнить, cmd
net stop msdtc
net start msdtc


И фсе запустилось :)

Green, спасибо. Ты настоящий друг, товарисч и брат!

23-07-2009 05:28
Не могу сказать. Покопайся в инете:
http://www.sql.ru/forum/actualthread.aspx?tid=191216
http://support.microsoft.com/default.aspx?scid=kb;en-us;205069

23-07-2009 05:11
Была выключена. Пытаюсь запустить - выдает ошибку. В системном журнале пишет: Служба "Координатор распределенных транзакций" завершена из-за внутренней ошибки 3221229584.

Эх, видно не судьба :(

А может права админа нужны?

23-07-2009 04:49
А служба Distributed Transaction Coordinator запущена в SQL Server Service Manager?

23-07-2009 04:41
Неверной дорогой идете, товарищ! :)
Гм, понял. Я собственно думал клиента написать с двумя TADOConnection и перекидывать данные из одного в другой, заодно и проверять: создать новую запись или обновить существующую.

В EMS SQL Manager 2005 замутил следующее:

select* from OpenRowSet('LCPI.IBProvider.3.Free','Password=***;Persist Security Info=True;User ID=***;Location=D:\Projects\AccessScale\db\SCALE.FDB;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 CARS')

На что получил по голове:
MSDTC on server 'ACHMIL_WS' is unavailable.
(ACHMIL_WS - имя компьютера)

Шо за зверь? :(

23-07-2009 04:22
в ADOConnection.ConnectionString записал: ...Provider=LCPI.IBProvider.3.Free

Неверной дорогой идете, товарищ! :)
Подключаться надо не к базе FB, а к базе MS SQL. А уже из базы MS SQL выполнять запрос, что-то типа:

SELECT * FROM OpenDataSource('Провайдер', 'Параметры')...ТаблицаFB


или

SELECT * FROM OpenRowSet('Провайдер', 'Параметры', 'SELECT * FROM ТаблицаFB')


23-07-2009 04:12
Ну, если найдешь OLE DB провайдер для Firebird
Установил бесплатный IBProvider, в ADOConnection.ConnectionString записал:

Provider=LCPI.IBProvider.3.Free;Password=***;Persist Security Info=True;User ID=***;Location=D:\Projects\AccessScale\db\SCALE.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"

Соединение с БД firebird устанавливается, хотя элементарная команда ADOConnection.GetTableNames не выполняется. Странно. Буду копать дальше.

то можно воспользоваться функциями OpenDataSource или OpenRowSet
Вот с этого места поподробней, пожалуйста :)

23-07-2009 02:48 | Сообщение от автора вопроса
Спасибо за направление мысли и ссылку. Интересный материал, вдумчиво изучаю.
В принципе, я думаю, что бесплатной версии мне будет вполне достаточно.

23-07-2009 02:26
Ну, если найдешь OLE DB провайдер для Firebird, то можно воспользоваться функциями OpenDataSource или OpenRowSet.
http://www.gotdotnet.ru/Forums/Data/135686.aspx

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Какой месяц идет после марта?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: 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» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

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