分享
 
 
 

ADO多表更新BCB實現

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

強烈感謝PPower.

ADO多表更新的代碼,welcome指正xuchaofei@jit.com.tw,

//-------------------------------------------------------------------------------------------------------------------------------------------

在.h文件中 定義一個這樣的結構:

struct FieldValue

{

AnsiString FNName;

Variant FNValue;

} ;

struct FieldInfor

{

std::vector<FieldValue> MyValue;

};

//-----------

在private部分中定義下面函數:

std::vector<FieldInfor>MyFieldInfor;

std::vector<FieldValue>TableField;

void __fastcall GetTheUpdateTable(std::vector<AnsiString>&TableName);

void __fastcall BeforePostEv(TDataSet *DataSet);

//-----------------------

在cpp文件中:

在訂義了多表的SQL語句的DataSet的BeforePost事件中加入如下代碼:

BeforePostEv(DataSet);

//-----------------------

void __fastcall TMutableOp::BeforePostEv(TDataSet *DataSet)

{

if(DataSet->Modified)

{

FieldInfor TempVector;

for(int i=0; i<DataSet->FieldCount; ++i)

{

FieldValue AllField;

AllField.FNName = DataSet->Fields->Fields[i]->FieldName;

AllField.FNValue = DataSet->Fields->Fields[i]->Value;

TempVector.MyValue.push_back(AllField);//把有數據更改的那個字段的數據的全部內容全部都保存起來。

}

MyFieldInfor.push_back(TempVector);

}

}

//---------------------------------

//假設已取得了改變了的字段,那麼對它進行比較,看是那個表的數據,分表更新。

void __fastcall TMutableOp::GetTheUpdateTable(std::vector<AnsiString>&TableName)

{

std::auto_ptr<TADOQuery>Query(new TADOQuery(NULL));

Query->Connection = ADOConnection1;

//-------------------------------------------------------------

for(std::size_t i=0;i< MyFieldInfor.size();++i) // 1 for

{

for(std::size_t t=0;t<TableName.size(); ++t)//按表名來分類處理

{

AnsiString KeyFieldID;

AnsiString KeyFieldValue;

TableField.clear();

for(std::size_t j=0; j< MyFieldInfor[i].MyValue.size(); ++j ) //3 for

{

//這裡是一個視圖被更改的一條記錄

//對記錄按表分類:

AnsiString StrTemp = MyFieldInfor[i].MyValue[j].FNName;

if(StrTemp.Delete(TableName[t].Length()+1,StrTemp.Length()) ==TableName[t])//

{ //如果是這個表的字段,如果是Key字段,則把它記下,如果不是,則讓它組成SQL語句

AnsiString Temp;

Temp = MyFieldInfor[i].MyValue[j].FNName;

Temp.Delete(1,TableName[t].Length());

Temp.Delete(5,Temp.Length());//除表名後的前面四個字符,看看是不是"_Key"

if(Temp == "_Key")

{//是關建字段 ;把數據存到一個項量裡

//把字段的附加信息除去

AnsiString TempA = MyFieldInfor[i].MyValue[j].FNName;;

TempA.Delete(1,TableName[t].Length());//把表名去除

TempA.Delete(1,5); //把_Key去除,得到真實字段名

FieldValue FieldStruct;

KeyFieldID = TempA;

KeyFieldValue = MyFieldInfor[i].MyValue[j].FNValue;

FieldStruct.FNName =TempA;

FieldStruct.FNValue = MyFieldInfor[i].MyValue[j].FNValue;

TableField.push_back(FieldStruct);

}

else

{

FieldValue FieldStruct;

AnsiString TempA = MyFieldInfor[i].MyValue[j].FNName;;

TempA.Delete(1,TableName[t].Length());//把表名去除

TempA.Delete(1,2); //把__去除

FieldStruct.FNName = TempA;

FieldStruct.FNValue = MyFieldInfor[i].MyValue[j].FNValue;

TableField.push_back(FieldStruct);

}

}

else

{

//如果表名不一樣,什麼也不做

}

}// 3 for

//對第一個表的數據,到此找完,因些在這裡做更新SQL語句的合成

if(TableField.size()==0)

return;

AnsiString SQL;

SQL =" Select ";

for(std::size_t v=0 ;v <TableField.size()-1 ;++v)

{

SQL+= TableField[v].FNName + " , ";

}

SQL += TableField[TableField.size()-1].FNName+" ";// 到些應組成了類如這樣的字串"Select FA,FB,FC "

//加上表名 +條件

SQL += " From "+ TableName[t]+ " Where "+ KeyFieldID +" = " + KeyFieldValue;

Query->SQL->Text = SQL;

Query->Open();//取出了這個表中符合這個ID條件的記錄。然後進行比較,後付值

while(!Query->Eof) //這 個SQL語句選 出來的結果只能有一條記。

{

for(int F=0; F< Query->FieldCount; ++F)

{

if(Query->Fields->Fields[F]->Value == TableField[F].FNValue);

else

{

{

Query->Edit();

Query->Fields->Fields[F]->Value = TableField[F].FNValue;

Query->Post();//更新回數據庫;

}

}

}

Query->Next();

}

Query->Close();

}

}

}

//--------------------------------------------------------------------

更新表的按扭代碼為:

std::vector<AnsiString>tableName;

tableName.push_back("AA");//AA為表名:,把要更改表的名稱插入Vector

tableName.push_back("BB");//BB為表名

GetTheUpdateTable(tableName);

//---------------------------------------------

OK啦。

記錄DataSet要設成批更新模式。切記,切記。

有些不好的地方就是SQL語句的寫法不是很好。但沒辦法。因為我還沒有解決我上面問到的題。

還有有些地方不合理,如果做了很多次的POST,每改動一條記錄就Post了一次,如果一次改過超萬條的話,這樣做可是不行的。!!!!!!!!!!!!!!!!!!!!!1

有很多沒有必要的空循環。

我只能通過SQL語句來加下相應的辨別信息:

如:

Select A.ID as AA_Key_ID,A.Name as AA__Name ,A.StdNO as AA__StdNO ,B.Mark as BB__Mark , B.ID as BB_Key_ID from AA as A,BB as B where A.stdNO = B.stdNO

//----------AA,BB為表名:

每個表的關建字段要給出:我用 "表名 + _Key +關建字段名"來表示,

每個字段的的名字都要用:"表名+ __ + 字段名來分別"

上面的SQL語句,如果沒有加上附加信息:SQL就像這個樣子:

Select A.Id,A.Name,A.stdNO,B.Mark,B.ID from AA as A,BB as B

所以寫SQL語句有些繁,這只是多表修改的,刪除 ,和新增的代碼 在理解些代碼的基礎下可寫出。

實現的思原則是:把每一條改動過記錄記錄下來,然後拿這個記錄按表分類。再拿它來和數據庫原數據進行比較,如果不一樣,改之。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有