Решил я написать для себя процедурку, которая перекачивала одинаковые по структуре таблицы из одной базы в другую. Знаю, что дело это неблагородное, и IBPump мне не переплюнуть, но нужна она мне, чтобы пользователь одну кнопочку нажал и все. Процедуру я оформил следующим образом в C++Builder:
Код: Выделить всё
void CopyIBTable(TIBDatabase *SourceDB,TIBDatabase *DestDB,String SourceTable,String DestTable,bool clear_dest)
{
Screen->Cursor=crHourGlass;
TIBTransaction *Read_Transaction=new TIBTransaction(Application);
TIBTransaction *Write_Transaction=new TIBTransaction(Application);
Read_Transaction->DefaultDatabase=SourceDB;
Write_Transaction->DefaultDatabase=DestDB;
Read_Transaction->Active=false;
Write_Transaction->Active=false;
SourceDB->AddTransaction(Read_Transaction);
DestDB->AddTransaction(Write_Transaction);
Read_Transaction->Params->Clear();
Read_Transaction->Params->Add("read");
Read_Transaction->Params->Add("read_committed");
Read_Transaction->Params->Add("rec_version");
Read_Transaction->Params->Add("nowait");
Write_Transaction->Params->Clear();
Write_Transaction->Params->Add("write");
Write_Transaction->Params->Add("concurrency");
Write_Transaction->Params->Add("nowait");
TIBQuery *RQuery=new TIBQuery(Application);
RQuery->Database=SourceDB;
RQuery->Transaction=Read_Transaction;
TIBQuery *WQuery=new TIBQuery(Application);
WQuery->Database=DestDB;
WQuery->Transaction=Write_Transaction;
if (clear_dest)
{
Write_Transaction->StartTransaction();
WQuery->Active=false;
WQuery->SQL->Text="DELETE FROM "+DestTable;
WQuery->ExecSQL();
Write_Transaction->Commit();
}
RQuery->Active=false;
RQuery->SQL->Text="SELECT * FROM "+SourceTable;
RQuery->Open();
String InsertSQL="INSERT INTO "+DestTable+(String)" (";
String FieldNames="",ParamsNames="";
for (int i=0;i<RQuery->FieldCount;i++)
{
FieldNames+=RQuery->Fields->Fields[i]->FieldName+",";
ParamsNames+=":"+RQuery->Fields->Fields[i]->FieldName+",";
}
FieldNames.Delete(FieldNames.Length(),1);
ParamsNames.Delete(ParamsNames.Length(),1);
InsertSQL+=FieldNames+") values ("+ParamsNames+")";
int counter=0;
Write_Transaction->StartTransaction();
WQuery->Active=false;
WQuery->SQL->Text=InsertSQL;
RQuery->First();
while (!RQuery->Eof)
{
for (int i=0;i<RQuery->FieldCount;i++)
{
WQuery->Params->Items[i]->AssignFieldValue(RQuery->Fields->Fields[i],RQuery->Fields->Fields[i]->OldValue);
}
WQuery->ExecSQL();
counter++;
RQuery->Next();
if (counter%1000==0)
{
Write_Transaction->Commit();
Write_Transaction->StartTransaction();
}
}
RQuery->Active=false;
WQuery->Active=false;
Write_Transaction->Active=false;
Read_Transaction->Active=false;
SourceDB->RemoveTransactions();
DestDB->RemoveTransactions();
delete RQuery;RQuery=NULL;
delete WQuery;WQuery=NULL;
delete Write_Transaction;Write_Transaction=NULL;
delete Read_Transaction;Read_Transaction=NULL;
Screen->Cursor=crDefault;
}
Решил попробовать данную процедуру на таблице, в которой 70000 тысяч записей и около тридцати полей. Проц у меня Celeron 2.2, оперативки 256, Firebird 1.5.3. Не густо, но думаю что такая задача для него особых трудностей вызывать не должна. В общем, 13 тысяч записей он за 10 минут с горем пополам перекачал (еле снял задачу, система повисла почти наглухо), почуял что что -то не так. Подскажите мне пожалуйста, что?
Конечно, скорее всего я изобретаю велосипед, я думаю что есть уже готовые процедуры, или методы решения, но что - то ничего не нашел. Может быть плохо искал...