关于导入数据的问题!

matlab7 2002-12-24 02:10:22
我现在想从以前备份的数据库中的某几个表导入数据,要求:假如导入的记录已经存在,则不写入;反之,写入。(这个是通过主键信息来判断的)
我想问,有没有某个函数可以实现记录的拷贝功能,而不必逐个字段的写?
我写的程序是这样的:
while(!SourceDataSet1->Eof)
{
try{
LoaclDataSet->Insert();
LocalDataSet->FieldByName("字段1")->Value = SourceDataSet->FieldByName("字段1")->Value;
LocalDataSet->FieldByName("字段2")->Value = SourceDataSet->FieldByName("字段2")->Value
LocalDataSet->FieldByName("字段3")->Value = SourceDataSet->FieldByName("字段3")->Value
......
LoaclDataSet->Post();
}catch(...)
{
FailRecNo++;
}
}
如何表多且每个表的字段数又多的话,上述代码就显得很罗嗦了喔!
...全文
58 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
matlab7 2002-12-27
  • 打赏
  • 举报
回复
香蕉,你在上述代码中写了那么多的循环语句,执行的效率是很低的,如果表中的记录数比较多的话,会造成程序无响应!
你能不能写出把一个数据库中的一个表拷贝到另外一个数据库中去的sql语句?如果能的话,就可以对统一个数据库中的两个表进行如下操作了:
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add(" insert into NTB select * from OTB ");
ADOQuery1->SQL->Add(" where Mid not in (select Mid from NTB)");
这样就可以不用循环语句了。

xpyilin 2002-12-26
  • 打赏
  • 举报
回复
我想了想,暂时也没有更好的办法,你的代码贴的不全,我不能很好的理解你使用的方法,我的方法如下:
ADOConnection1,ADOConnection2分别连接不同的数据库。。。
ADOQuery1连接ADOConnection1;
ADOQuery2,ADOQuery3连接ADOConnection2;

int count = 0;//计数器
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add(" select * from 旧表 ");
ADOQuery1->Open();
ADOQuery1->First();
ADOQuery2->Close();
ADOQuery2->SQL->Clear();
ADOQuery2->SQL->Add(" select * from 新表");
ADOQuery2->Open();
ADOQuery2->First();
if (ADOQuery2->RecordCount == 0)//新表没有数据,则旧表数据全部插入
{
for (int i=0;i<ADOQuery1->RecordCount;i++)
{
ADOQuery3->Close();
ADOQuery3->SQL->Clear();
ADOQuery3->SQL->Add(" insert into 新表 values(:p1,:p2,:p3)");//假设有三个域
for (int j=0;j<ADOQuery2->FieldCount;j++)
{
ADOQuery3->Parameters->Items[j]->Value = ADOQuery1->Fields->Fields[j]->AsString;
}
ADOQuery3->ExecSQL();
ADOQuery1->Next();
}
return;
}
for (int i=0;i<ADOQuery1->RecordCount;i++ )//对两表数据进行比较,新表中没有的数据则插入
{
for (int j=0;j<ADOQuery2->RecordCount;j++)
{
if ( ADOQuery1->Fields->Fields[0]->AsString ==
ADOQuery2->Fields->Fields[0]->AsString)//如果新表中存在该数据,则比较下一条
{
ADOQuery2->First();//新表从新定位表首记录
ADOQuery1->Next();//旧表记录下移
count = 0;//计数器归零
break;
}
else //当前记录不相同,新表记录下移,旧表记录保持不变
{
count = count + 1;
ADOQuery2->Next();
}
if ( count == ADOQuery2->RecordCount)//比较完所有记录,仍没有相同的,则插入该记录到新表
{
ADOQuery3->Close();
ADOQuery3->SQL->Clear();
ADOQuery3->SQL->Add(" insert into 新表 values(:p1,:p2,:p3)");
for (int j=0;j<ADOQuery2->FieldCount;j++)
{
ADOQuery3->Parameters->Items[j]->Value = ADOQuery1->Fields->Fields[j]->AsString;
}
ADOQuery3->ExecSQL();
count = 0;
}
}
ADOQuery1->Next();
}
这是一个比较通用的方法,当然不可避免的使用了循环,对于同时操作两个或以上的数据库,我没有实践的经验,但是我想至少ACCESS不支持SQL同时操作两个库。。。
xpyilin 2002-12-26
  • 打赏
  • 举报
回复
两张表是不同的数据库的当然不行了。。。
Sorry 没有明白你的意思,我想想。。。
matlab7 2002-12-26
  • 打赏
  • 举报
回复
香蕉:
我的两张表是不同数据库的,这种方法还行了?
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add(" insert into NTB select * from OTB ");
ADOQuery1->SQL->Add(" where Mid not in (select Mid from NTB)");
白蛇:
我用的是ADO而不是BDE。
真如实观 2002-12-26
  • 打赏
  • 举报
回复
如果用的是BDE,可以用BatchMove。
xpyilin 2002-12-25
  • 打赏
  • 举报
回复
控件换成Query也可,如果楼主没有试过,建议试一下,在程序中循环和数据库直接操作无论在速度,难易度等方面都是不可同日而语的。。。
xpyilin 2002-12-25
  • 打赏
  • 举报
回复
其实,也可以通过如下方法,当然。。。嘻嘻~~~~我们只讨论实现方式:
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add( " delete table NTB ");
ADOQuery1->ExecSQL();
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select * into NTB from (select * from OTB)");
ADOQuery1->ExecSQL();
这样也能达到同样的效果。。。
xpyilin 2002-12-25
  • 打赏
  • 举报
回复
确实可以通过一条SQL语句完成而不用写循环等。。。我基本同意genphone_ru(票票) 的方法。假设你用的是ADOQuery组件,而两个表分别是NTB(新),OTB(旧),主键都是Mid,当然两个表的结构要求一致,那么:
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add(" insert into NTB select * from OTB ");
ADOQuery1->SQL->Add(" where Mid not in (select Mid from NTB)");
ADOQuery1->ExecSQL();
这样就能达到楼主你的要求。。。
devie 2002-12-24
  • 打赏
  • 举报
回复
用循环吧,先判断后写入。
void __fastcall TForm1::Button2Click(TObject *Sender)
{
AnsiString strSql;
AnsiString strName;
AnsiString strType;
AnsiString strMent;

Screen->Cursor=crHourGlass;
m_sdCon->Open();
m_erpCon->Open();
m_sdTable->Open();
m_erpTable->Open();
m_erpTable->First();
while(!m_erpTable->Eof)
{
strName=m_erpTable->FieldByName("name")->AsString;
strSql="select * from scripts where name='"+strName+"'";
m_sdQuery->Close();
m_sdQuery->SQL->Clear();
m_sdQuery->SQL->Add(strSql);
m_sdQuery->Open();
if(m_sdQuery->RecordCount<1)
{
strType=m_erpTable->FieldByName("type")->AsString;
strMent=m_erpTable->FieldByName("statement")->AsString;


m_sdTable->Append();
m_sdTable->FieldByName("name")->AsString=strName;
m_sdTable->FieldByName("type")->AsString=strType;
m_sdTable->FieldByName("statement")->AsString=strMent;
m_sdTable->Post();
}
m_erpTable->Next();
}
Screen->Cursor=crDefault;
}
hopelhs 2002-12-24
  • 打赏
  • 举报
回复
可以用BatchMove
票票飞扬 2002-12-24
  • 打赏
  • 举报
回复
SourceDataSet1->Close;
SourceDataSet1->SQL->Clear;
SourceDataSet1->SQL->Text = 'INSERT INTO TableDest SELECT * FROM TableSource WHERE ID not in (SELECT ID from TableDest)';
SourceDataSet1->ExecSQL;
matlab7 2002-12-24
  • 打赏
  • 举报
回复
打错字,不好意思!
◆如果表多且每个表的字段数又多的话◆

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧