Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 447

/ вопрос открыт /

Здравствуйте, эксперты!
Перерыл интернет простую задачу не могу решить.
Имеются 100 шт баз данных Access надо соединить их в одну(програмно).Но особенность не все поля нужно использовать.
Используя SQL создаю запрос, Адоконнест с базой - конектится и с Baza1 и Baza2, здесь всё нормально.
TableBaz -таблица с именами баз данных.

DatM.ADOQuery.SQL.Text:='INSERT INTO OSN (O_Grom,O_Grup,O_Fip,O_DatPr,O_DatPrPr)'+
' IN "' + Baza1 + '" Select (' + DatM.TableBaz.FieldByName('B_ID').AsString+
', b1.G_Nazva, b2.O_Fip, b2.O_DatPrun, b2.O_DatPrPr) from gromada as b1,osnovn as b2 in "' + Baza2+'"'+
' where O_Gromada=G_Id ';

DatM.ADOQuery.ExecSQL;
На этом этапе вылетает ошибка
Exception class EOleException with message 'Ошибка синтаксиса (запятая) в выражении запроса '(20, b1.G_Nazva, b2.O_Fip, b2.O_DatPrun, b2.O_DatPrPr)''.

Как нужно поправить запрос ?
Вот здесь оно работает: http://www.delphikingdom.com/asp/answer.asp?IDAnswer=70503

Lytvynenko Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Lytvynenko (статус: Посетитель)
Вопрос отправлен: 25 ноября 2009, 14:50
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 13; последнее сообщение — 26 ноября 2009, 16:48; участников в обсуждении: 2.
Вадим К

Вадим К (статус: Академик), 25 ноября 2009, 15:01 [#1]:

Вы пытаетесь сделать "гетерогенный запрос", то есть, взять данные с одной базы и положить в другую (это разные mdb файлы). Я прав?
Галочка "подтверждения прочтения" - вселенское зло.
Lytvynenko

Lytvynenko (статус: Посетитель), 25 ноября 2009, 15:35 [#2]:

круглые скобки нужно было убрать...Но ошибки еще есть.
Lytvynenko

Lytvynenko (статус: Посетитель), 25 ноября 2009, 15:37 [#3]:

Да это разные базы данных , ну и с разными таблицами.
Просто часть информации нужно слить в одну табличку
Вадим К

Вадим К (статус: Академик), 25 ноября 2009, 15:42 [#4]:

ну понятно, что если базы разные, то и таблицы разные. АДО не умеет делать гетерогенный запрос. просто не умеет. поэтому в одном SQL запросе нельзя смешивать две разные базы. И точка.

Такое дело можно провернуть только через BDE. (это наверно единственный его плюс).
Либо классически. делаем выборку, по одной записи проходим и записываем в другую базу.

Можно ещё интересней. подключаемся к каждой базе и импортируем данные в csv файл или сразу в файл, в котором хранятся INSERT'ы. А потом одной строкой заливаем назад все в одну базу.
Галочка "подтверждения прочтения" - вселенское зло.
Lytvynenko

Lytvynenko (статус: Посетитель), 25 ноября 2009, 16:13 [#5]:

Вот это SQL глотнуло и выборка правильная идет.
Но теперь проблема: с ошибкой
'Невозможно использовать 'E:\Secr\tabl.mdb'; файл уже используется' Пробывал прописать конект
DatM.ADOQuery.ConnectionString:=
Но оно кричит к другому не могу подключиться без пароля
DatM.ADOQuery.SQL.Text:='INSERT  INTO  OSN (O_Grom,O_Grup,O_Fip,O_DatPr,O_DatPrPr)'+
          ' IN "' + Baza_1 + '" Select  ' + DatM.TableBaz.FieldByName('B_ID').AsString+
          ', b1.G_Nazva, b2.O_Fip, b2.O_DatPrun, b2.O_DatPrPr from gromada as b1,osnovn as b2  in "' + Baza2+'"'+
          ' where O_Gromada=G_Id ';
Lytvynenko

Lytvynenko (статус: Посетитель), 25 ноября 2009, 16:19 [#6]:

В справочнике умные люди пишут:
Синтаксис
Запрос на добавление нескольких записей:

INSERT INTO назначение [(поле_1[, поле_2[, ...]])] [IN внешняяБазаДанных]
SELECT [источник.]поле_1[, поле_2[, ...]
FROM выражение

Где выражение - Имена таблицы или таблиц, откуда вставляются данные. Это выражение может быть именем отдельной таблицы или результатом операции INNER JOIN, LEFT JOIN или RIGHT JOIN, а также сохраненным запросом.

Заинтересовала посленяя фраза "сохраненный запрос"
Примерчик есть на это: ? / импортируем данные в csv файл или сразу в файл, в котором хранятся INSERT'ы/
Не хочется построчно ходить...
Lytvynenko

Lytvynenko (статус: Посетитель), 25 ноября 2009, 16:51 [#7]:

Да, сейчас поджимает придется делать построчно...

НО если у кого то есть оригинальный метод как указал Вадим К. буду благодарен, в будущем пригодится.

Тему можно закрыть. так как Адо не могёт- сам убедился.
Спасибо всем....
Вадим К

Вадим К (статус: Академик), 25 ноября 2009, 16:55 [#8]:

Цитата (Lytvynenko):

Примерчик есть на это: ? / импортируем данные в csv файл или сразу в файл, в котором хранятся INSERT'ы/
Не хочется построчно ходить...

А в чем сложность пройтись построчно? и сразу в файл писать в виде "insert into ...."
А потом отркываем акссес и там есть импорт
Галочка "подтверждения прочтения" - вселенское зло.
Lytvynenko

Lytvynenko (статус: Посетитель), 25 ноября 2009, 23:36 [#9]:

Да нет не сложность, просто любопитство испробывать найденнын варианты.
А с примером всё получилось.: для новичков С ADO надо вот так: работает

DatM.ADOQuery2.Active:=False;
    DatM.ADOQuery2.SQL.Text:='Select ' + DatM.TableBaz.FieldByName('B_ID').AsString+
          ', b1.G_Nazva, b2.O_Fip, b2.O_DatPrun, b2.O_DatPrPr from gromada as b1,osnovn as b2  '+
          ' where O_Gromada=G_Id order by G_Id';
    DatM.ADOQuery2.Active:=True;
 
        DatM.ADOQuery.SQL.Text:='INSERT  INTO  OSN (O_Grom,O_Grup,O_Fip,O_DatPrun,O_DatPrPr)'+
          ' IN "' + Baza_1 + '" Values (:grom, :grup, :fip, :datpr, :PrPr)';
 
 
    DatM.ADOQuery2.First;
    while not DAtM.ADOQuery2.eof do
       begin
          DatM.ADOQuery.Parameters.ParamByName('grom').Value := DatM.TableBaz.FieldByName('B_ID').AsInteger;
          DatM.ADOQuery.Parameters.ParamByName('grup').Value := DatM.ADOQuery2.FieldByName('G_Nazva').AsString;
          DatM.ADOQuery.Parameters.ParamByName('fip').Value := DatM.ADOQuery2.FieldByName('O_Fip').AsString;
          DatM.ADOQuery.Parameters.ParamByName('datpr').Value := DatM.ADOQuery2.FieldByName('O_DatPrun').AsDateTime;
          DatM.ADOQuery.Parameters.ParamByName('prpr').Value := DatM.ADOQuery2.FieldByName('O_DatPrPr').AsInteger;
          DatM.ADOQuery.ExecSQL;
          DAtM.ADOQuery2.Next;
       end;
Lytvynenko

Lytvynenko (статус: Посетитель), 26 ноября 2009, 00:24 [#10]:

Но честно признаться хотелось бы быстрее, когда пачкой идет так оно и жить веселее.
Вадим К

Вадим К (статус: Академик), 26 ноября 2009, 11:34 [#11]:

Я перефразирую. Да, лень - полезное качество программиста, когда он вместо ста строк кода пишет 5, и оно работает также.
Но иногда дешевле просто написать 30 строк, оно тоже будет работать, а потом пойти погулять и краем уха подумать о лучшем коде.


В приведенном выше коде многие новички могут сделать одну большую глупость. Если много данных перебрасывается, то добавляют Application.ProcessMessage; и progressBar... Они тормозят процесс очень хорошо и в некоторых случаях полезный код занимает 10% времени:))
Галочка "подтверждения прочтения" - вселенское зло.
Lytvynenko

Lytvynenko (статус: Посетитель), 26 ноября 2009, 16:44 [#12]:

Понимаю.
Но для визуализации использовать лучше progressBar
с свойством Style: pbstMarquee, ну и Position : 50
И пускай себе бегает . Отображает во время выполнения что что-то делается , а после выполнения убираю. Бутафория, но приятно...
Вадим К

Вадим К (статус: Академик), 26 ноября 2009, 16:48 [#13]:

Если хочется действительно прогресс, то его можно сделать. Вначале запросом select Count(*) from имя_таблицы запрашивается кол-во записей. Теперь смотрим размер прогрессбара. Если записей 100тыс, а размер прогресса 100 пикселей, то обновлять прогресс между 5001 и 5004 записью не стоит - всё равно визуально это не будет никак видно, прогесс ни на пиксель не сдвинеться!
А вся проблема в том, что когда мы вызываем ProgressBar1.Progres := чему то там, то прогресс полностью перерисовывается в любом случае... вот такой глюк винды (да, да , это у винды)
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:29
Выполнено за 0.03 сек.