|
Вопрос # 2 128/ вопрос открыт / |
|
Доброго времени суток, уважаемые эксперты!
Скажите как правильно сформировать алгоритм по обмену данными между 2 одинаковыми базами (аксесс) но которые находятся на разных дисках.
Но условие такое , если запись с ID есть в обеих таблицах то обновление данных.
Если ключ только в одной таблице то вставка записи.
я тут пробовала делать так (может и коряво ... как умею)
использую 2 ADOConnection для соединения с базами.
Приложение: Переключить в обычный режим-
-
- i,g,j:integer;
-
-
-
-
-
- With DataModule1.Connection do
- Begin
- Connected:=False; ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data
Source='+GetCurrentDir+'\Zalob.mdb;Mode=ReadWrite;Persist Security Info=False';
- Connected:=True;
- End;
-
-
-
-
- With ADOConnection1 do
- Begin
- Connected:=False;
- ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=L:\..\...\Zalob.mdb;Mode=ReadWrite;Persist Security Info=False';
- Connected:=True;
- End;
-
-
-
-
- ADOQuery2-DataModule1.Connection
-
-
-
-
- with ADOQuery1 do
- begin
- close;
- sql.Clear;
- sql.Add('select * from Zurnal order by PorNomer');
- Open;
- end;
- with ADOQuery2 do
- begin
- close;
- sql.Clear;
- sql.Add('select * from Zurnal order by PorNomer');
- Open;
- end;
-
-
-
-
-
- while not ADOQuery1.Eof do begin
- g:=StrToInt(ADOQuery1.Fields.Fields[1].AsString);
- j:=StrToInt(ADOQuery2.Fields.Fields[1].AsString);
-
- tex:='update Zurnal set StatusKol ='+QuotedStr(ADOQuery2.Fields.Fields[3].AsString)+',fio='
+QuotedStr(ADOQuery2.Fields.Fields[4].AsString)+
',KemPereslano='+QuotedStr(ADOQuery2.Fields.Fields[5].AsString)+',Adress='+QuotedStr(ADOQuery2.Fields.Fields[6].AsString)+',Soderganie='+QuotedStr(ADOQuery2.Fields.Fields[7].AsString)+',Ispolnitel='+QuotedStr(ADOQuery2.Fields.Fields[8].AsString)+',Status='+QuotedStr(ADOQuery2.Fields.Fields[9].AsString)+',Ident='+QuotedStr(ADOQuery2.Fields.Fields[11].AsString)+'';
- if TryStrToDateTime(DateTimeToStr(ADOQuery2.Fields.Fields[2].AsDateTime), d) then tex:=tex + ',
DataPost='+QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[2].AsDateTime))+'';
- if TryStrToDateTime(DateTimeToStr(ADOQuery2.Fields.Fields[10].AsDateTime), d) then tex:=tex+ ',
DataIspolnen='+QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[10].AsDateTime))+'';
- tex:=tex+ ' where PorNomer = '+QuotedStr(ADOQuery1.Fields.Fields[1].AsString)+'';
- ADOQuery3.Close;
- ADOQuery3.SQL.Clear;
- ADOQuery3.SQL.Text:=tex;
- ADOQuery3.ExecSQL;
- end else begin
- tex:= 'insert into Zurnal
(PorNomer,DataPost,StatusKol,fio,KemPereslano,Adress,Soderganie,Ispolnitel,Status,DataIspolnen,Ident)
values('+QuotedStr(ADOQuery2.Fields.Fields[1].AsString)+','+QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[2].AsDateTime))+','+QuotedStr(ADOQuery2.Fields.Fields[3].AsString)+','+QuotedStr(ADOQuery2.Fields.Fields[4].AsString)+','+QuotedStr(ADOQuery2.Fields.Fields[5].AsString)+','+QuotedStr(ADOQuery2.Fields.Fields[6].AsString)+','+QuotedStr(ADOQuery2.Fields.Fields[7].AsString)+','+QuotedStr(ADOQuery2.Fields.Fields[8].AsString)+','+QuotedStr(ADOQuery2.Fields.Fields[9].AsString)+','+QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[10].AsDateTime))+','+QuotedStr(ADOQuery2.Fields.Fields[11].AsString)+')';
-
- ADOQuery3.Close;
- ADOQuery3.SQL.Clear;
- ADOQuery3.SQL.Text:=tex;
- ADOQuery3.ExecSQL;
- end;
- ADOQuery1.next;
- end;
 |
Вопрос задала: Танюшка (статус: Посетитель)
Вопрос отправлен: 26 ноября 2008, 17:07
Состояние вопроса: открыт, ответов: 2.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, Танюшка!
А всё ведь проще надо делать. Для одной базы делаем Select * from table и пробегая в цикле по ней, выполняем select * from table2 where id=ид_с_первой таблицы
Если запись есть - делаем сверку по другим полям и по надобности записываем ид в специальный файл/массив/StringList. Если записи нет (возвратит Query.RecordCount = 0), то добавим в другой массив -там где храним номера для добавления. То есть, пока сверяем, базу не модифицируем.
А потом, имея на руках "протоколы сверки", добавляем.
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 26 ноября 2008, 18:04
Оценка за ответ: 5
|
Ответ #2. Отвечает эксперт: Косолапов Дмитрий Юрьевич
Здравствуйте, Танюшка!
Не совсем согласен с мнением Вадима К - запросы в цикле представляются нерациональными... Вместо этого я бы предложил во втором запросе (или даже таблице) делать поиск с использованием индекса (ID ведь первичный ключ).
Также могу предложить вместо "ручной" сверки использовать стандартные возможности по репликации MS Access.
Мини-форум вопроса
Всего сообщений: 4; последнее сообщение — 29 ноября 2008, 10:05; участников в обсуждении: 3.
|
Вадим К (статус: Академик), 27 ноября 2008, 09:56 [#1]:
to Косолапов Дмитрий Юрьевич
Вам кажеться или вы пробовали? Некоторые движки БД поиск реализуют крайне хитрым оборазом - они просто проходят сверху вниз по записям и смотрят. А это будет ещё медленее. В случае select (который будет возвращать либо 0, либо одну запись) это будет значительно эффективней на больших объемах.
Конечно, можно сделать сортировку по этому ключу и аккуратно паралельно продвигаться, но для такой качественно реализовать такой алгоритм надо ещё уметь.
А вот использовать встроенные методы - это обычно самый "эффективный путь". Хотя и тут можно постараться
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Косолапов Дмитрий Юрьевич (статус: 8-ой класс), 28 ноября 2008, 10:47 [#2]:
"они просто проходят сверху вниз по записям и смотрят" - нет, такой поиск нам не нужен, конечно же Я имел в виду нормальный поиск по индексу.
|
|
Танюшка (статус: Посетитель), 28 ноября 2008, 11:06 [#3]:
спасибо вадим!!!!!
я воспользовалась вашим советом но немного по другому:
while not ADOQuery2.Eof do
begin
tex:='update Zurnal set StatusKol =' + QuotedStr(ADOQuery2.Fields.Fields[3].AsString) + ',fio=' + QuotedStr(ADOQuery2.Fields.Fields[4].AsString) + ',KemPereslano=' + QuotedStr(ADOQuery2.Fields.Fields[5].AsString)+ ',Adress=' + QuotedStr(ADOQuery2.Fields.Fields[6].AsString) + ',Soderganie=' + QuotedStr(ADOQuery2.Fields.Fields[7].AsString) + ',Ispolnitel=' + QuotedStr(ADOQuery2.Fields.Fields[8].AsString) + ',Status=' + QuotedStr(ADOQuery2.Fields.Fields[9].AsString) + ',Ident=' + QuotedStr(ADOQuery2.Fields.Fields[11].AsString) + '';
if TryStrToDateTime(DateTimeToStr(ADOQuery2.Fields.Fields[2].AsDateTime), d) then tex:=tex + ', DataPost=' + QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[2].AsDateTime)) + '';
if TryStrToDateTime(DateTimeToStr(ADOQuery2.Fields.Fields[10].AsDateTime), d) then tex:=tex+ ', DataIspolnen=' + QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[10].AsDateTime)) + '';
tex:=tex+ ' where PorNomer = ' + QuotedStr(ADOQuery2.Fields.Fields[1].AsString) + '';
ADOQuery3.Close;
ADOQuery3.SQL.Clear;
ADOQuery3.SQL.Text:=tex;
ADOQuery3.ExecSQL;// ADOQuery3 связан с таблицей на сервере(которую обнавляю)
if (ADOQuery3.ExecSQL=0) then begin
tex:= 'insert into Zurnal (PorNomer, DataPost, StatusKol, fio, KemPereslano, Adress, Soderganie, Ispolnitel, Status, DataIspolnen, Ident) values(' + QuotedStr(ADOQuery2.Fields.Fields[1].AsString) + ',' + QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[2].AsDateTime)) + ',' + QuotedStr(ADOQuery2.Fields.Fields[3].AsString) + ',' + QuotedStr(ADOQuery2.Fields.Fields[4].AsString) + ',' + QuotedStr(ADOQuery2.Fields.Fields[5].AsString)+ ',' + QuotedStr(ADOQuery2.Fields.Fields[6].AsString) + ',' + QuotedStr(ADOQuery2.Fields.Fields[7].AsString) + ',' + QuotedStr(ADOQuery2.Fields.Fields[8].AsString) + ',' + QuotedStr(ADOQuery2.Fields.Fields[9].AsString) + ',' + QuotedStr(DateTimeToStr(ADOQuery2.Fields.Fields[10].AsDateTime)) + ',' + QuotedStr(ADOQuery2.Fields.Fields[11].AsString) + ')';
ADOQuery3.Close;
ADOQuery3.SQL.Clear;
ADOQuery3.SQL.Text:=tex;
ADOQuery3.ExecSQL;
end;
ADOQuery2.Next;
end;
//ADOQuery2 связан с таблицей которая на рабочем диске
выкладываю для тех кому интересно....
можете пообсуждать рациональность данного куска кода
|
|
Косолапов Дмитрий Юрьевич (статус: 8-ой класс), 29 ноября 2008, 10:05 [#4]:
ADOQuery3.ExecSQL;// ADOQuery3 связан с таблицей на сервере(которую обнавляю)
if (ADOQuery3.ExecSQL=0)
В этом месте запрос дважды выполняется.
В целом, весьма жесткая синхронизация. Устраивает ли производительность? А стандартной репликацией точно не хотите пользоваться?
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|