分享
 
 
 

C\S结构中成批保存CLIENTDATASET中的数据

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

这应该不算是什么技巧,估计有数据库方面程序的DELPHI程序员都知道;本来没有写想到

需要把它写成一篇贴子,但前不久看个别刚入门的兄弟的代码时。才发展他们还在刀

耕火种,为此才想把它写出来算是对入门的兄弟们的一点帮助,让大侠们见笑了;

我们都知道TCLIENTDATASET有把对它其中的数据所做的修改记录下来的功能;如果需要还可以将

修改回复到以前的某个状态,而且结合DATASETPROVIDER还可能自动完成改动到SQL映射,将改动成批提交到数据库中

这个特性对于写数据库程序来说非常有用。其实我所说的保存CLIENTDATASET的数据也是利用这个特性来实现的;

代码很简单:

unit uCDSSave;

interface

uses

SysUtils, Windows, Messages, Classes, Graphics, Controls,

Forms, Dialogs,Provider,DBClient,DB,Variants;

type

TSaveCDS = class (TObject)

private

Fileds: TStrings;

FProvider: TDataSetProvider;

procedure ReconcileError(DataSet: TCustomClientDataSet; E: EReconcileError;

UpdateKind: TUpdateKind; var Action: TReconcileAction);

public

constructor Create;

destructor Destroy; override;

procedure CDSSave(CDS:TClientDataSet;TableName,keyFiled,

NoSaveFileds:String;KeyUpdate:Boolean=False);

procedure DataSetProviderUpdateData(Sender: TObject;DataSet:

TCustomClientDataSet);

procedure SetCDS(KeyFiled,NoSavefields:string;KeyUpdate:Boolean=False);

property Provider: TDataSetProvider read FProvider write FProvider;

end;

implementation

{

*********************************** TSaveCDS ***********************************

}

constructor TSaveCDS.Create;

begin

inherited Create;

Fileds:=TStringList.Create;

FProvider:=TDataSetProvider.Create(nil);

FProvider.UpdateMode:= upWhereKeyOnly ;

FProvider.Options:=FProvider.Options+[poAllowMultiRecordUpdates];

end;

destructor TSaveCDS.Destroy;

begin

FreeAndNil(FProvider);

FreeAndNil(Fileds);

inherited Destroy;

end;

procedure TSaveCDS.CDSSave(CDS:TClientDataSet;TableName,keyFiled,

NoSaveFileds:String;KeyUpdate:Boolean=False);

var

ErrCount: Integer;

begin

CDS.CheckBrowseMode;

if CDS.ChangeCount<1 then Exit;

CDS.OnReconcileError:= ReconcileError; //调用保存前客户代码应该先调用SetCDS指定保存的信息;

// SetCDS(CDS,keyFiled,NoSaveFileds,KeyUpdate);

// FProvider.ApplyUpdates(CDS.Delta,0,ErrCount)

try

CDS.Reconcile(FProvider.ApplyUpdates(CDS.Delta,0,ErrCount));

finally

CDS.OnReconcileError:=nil;

end;

end;

procedure TSaveCDS.DataSetProviderUpdateData(Sender: TObject;DataSet:

TCustomClientDataSet);

var

i: Integer;

v: OLEVariant;

KeyUpdate: Boolean;

begin

varClear(v);

V:=DataSet.GetOptionalParam('KEYUPDATE');

if not (VarIsNull(V) or VarIsClear(V)) then KeyUpdate:=true

else KeyUpdate:=False;

V:=DataSet.GetOptionalParam('KEYFILED');

if Assigned(DataSet.FindField(VarToStr(V))) then

if KeyUpdate then

DataSet.FindField(VarToStr(V)).ProviderFlags:=[pfInupdate,pfinKey]

else

DataSet.FindField(VarToStr(V)).ProviderFlags:=[pfinKey];

V:=DataSet.GetOptionalParam('NOSAVEFILEDS');

if (VarIsNull(V) or VarIsClear(V)) then Exit;

Fileds.Clear;

Fileds.Text:=VarToStr(V);

if Fileds.Count<1 then Exit; //将不保存的传过来 ,在这个事件中解析

//这只是一种方法而已,当然也有其他的方式,如用BYTE数组打包到数据包中;请读者自已考虑实现了;

for i:=1 to Fileds.Count-1 do

if Assigned(DataSet.FieldByName(Fileds[i])) then DataSet.FieldByName(Fileds[i]).ProviderFlags:=[];

end;

procedure TSaveCDS.ReconcileError(DataSet: TCustomClientDataSet; E:

EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction);

begin

Raise E; //只是简单的抛出例外,如有自己的处理请自己实现了;

end;

procedure TSaveCDS.SetCDS(KeyFiled,NoSavefields:string;KeyUpdate:Boolean=False);

begin

CDS.SetOptionalParam('TABLE_NAME' ,TableName,true);//指定要存入的表名;

CDS.SetOptionalParam('KEYFILED' ,keyFiled,true);//指定要主建名;

CDS.SetOptionalParam('NOSAVEFILEDS' ,NoSaveFileds,true);//指定不要存入的字段列表;

if KeyUpDate then

CDS.SetOptionalParam('KEYUPDATE' ,1,true);// 指定主健是否要更新字段列表

end;

end.

这段代码不一定是最优的实现,主要是想给出一个思路,用时可以根据实际情况改动,例如:本来程序是用的MIDAS来实现,则

就可以直接用CLIENTDATASET连接中间的TDATASETPROVIDER来实现;有一点要特别说明的是我发现在D5时,在前端的CLIENTDATASET

中直接设定各个字段的PROVIDERFLAG后不会被打包到Delta传给TDATASETPROVIDER;D7中好象也有此问题,不知是我看错了,还是D的BUG;

否则就不用那么麻烦自已写代码来处理了;

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有