国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C/S結構中成批保存CLIENTDATASET中的數據

2019-11-18 18:01:06
字體:
來源:轉載
供稿:網友
 

這應該不算是什么技巧,估計有數據庫方面程序的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;
  否則就不用那么麻煩自已寫代碼來處理了;


上一篇:角點檢測算子的代碼描述

下一篇:解決無法按y軸顯示的問題!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 翁牛特旗| 霍山县| 吕梁市| 巫山县| 称多县| 西丰县| 安乡县| 龙川县| 靖远县| 南召县| 柳林县| 三原县| 大化| 扬州市| 永康市| 洮南市| 赫章县| 郑州市| 永仁县| 扎鲁特旗| 樟树市| 万山特区| 牙克石市| 沈阳市| 贵溪市| 淮滨县| 广元市| 连江县| 南丹县| 正宁县| 上蔡县| 舟山市| 和田市| 石首市| 刚察县| 襄城县| 台山市| 剑川县| 绥宁县| 绥化市| 榆树市|