最近維護一個項目,裏面用到ClientDataSet,因爲以前接觸ClientDataSet比較少,因此這個星期補了一下關於ClientDataSet的知識,並在此記錄下我所瞭解到的並應用到實際項目中的ClientDataSet的知識。數據庫
項目新需求:1.從別的數據庫導入物料資料,並容許操做員作修改後保存提交;2.從別的數據庫導入價格資料,並容許操做員作出修改並保存;3.記錄相應的日誌。4.容許操做員過濾關鍵字查找。app
(PS:項目的數據鏈接模式爲:ADOConnection→ADOQuery→DataSetProvider→ClientDataSet→DataSource→數據集顯示控件,包括DBGrid,DBLookupComboboxEh等)ide
更新單條記錄spa
If cdsRecord.UpdateStatus <> usUnModified then //讓clientdataset處於非編輯狀態
Raise Exception.Create('You must apply updates before refreshing the current record.');
cdsRecord.RefreshRecord;//更新單條記錄,此處要注意,不單要在ClientDataSet中設置主鍵,要去對應的adoquery設置主鍵(ProviderFlags的pfInKey設置爲true)日誌
過濾code
cdsRecord.Filtered := False;
cdsRecord.Filter := 'itemcode='+QuotedStr(code);
cdsRecord.Filtered := True;orm
若是過濾條件爲空,則顯示所有記錄blog
cdsRecord.Filtered := False;
cdsRecord.Filter :='itemcode like '+QuotedStr('%%');
cdsRecord.Filtered := True;事件
過濾條件集添加「所有」記錄內存
cdsLookUp.Close;
cdsLookUp.CommandText := 'select * from jc_zd_item';
cdsLookUp.Open;
cdsLookUp.First;
cdsLookUp.InsertRecord(['','所有','','QB']);
記錄日誌
在提交前的事件cdsRecordBeforeApplyUpdates中處理
procedure TForm1.cdsRecordBeforeApplyUpdates(Sender: TObject; var OwnerData: OleVariant); var csdTemp: TClientDataSet; i : Integer; begin //準備提交 if not (cdsRecord.ChangeCount>0) then //判斷數據集是否有更改,ChangeCount>0表示有更改 Exit; csdTemp := TClientDataSet.Create(nil); csdTemp.Data := cdsRecord.Data;//複製數據集,不然在這個事件裏面處理自身的數據集會進入死循環 csdTemp.First; if not adqLog.Active then //adqLog是鏈接日誌表的ADOQuery,屬性LockType選擇ltBatchOptimistic(批量提交),這就能夠在提交前記錄好日誌,在提交後再把日誌批量上傳 adqLog.Active := True; for i:=0 to csdTemp.RecordCount-1 do //whilt not csdTemp.eof do同理 begin if csdTemp.UpdateStatus=usModified then //若是當前記錄是修改的 begin adqLog.Append; adqLog.FieldByName('pk').AsString := 'itemcode'; adqLog.FieldByName('newValue').AsString := csdTemp.FieldByName('itemcode').AsString; adqLog.FieldByName('remark').AsString := '修改'; adqLog.FieldByName('oldvalue').AsString := csdTemp.FieldByName('itemcode').OldValue; adqLog.Post; ShowMessage(IntToStr(Integer(csdTemp.UpdateStatus))); end; if csdTemp.UpdateStatus=usInserted then //若是當前記錄是新增的 begin adqLog.Append; adqLog.FieldByName('pk').AsString := 'itemcode'; adqLog.FieldByName('newValue').AsString := csdTemp.FieldByName('itemcode').AsString; adqLog.FieldByName('remark').AsString := '新增'; adqLog.FieldByName('oldvalue').AsString := ''; adqLog.Post; end; csdTemp.Next; end; end;
批量提交修改後的clientdataset數據集
if cdsRecord.State in [dsEdit, dsInsert] then //判斷數據集是否在編輯狀態,若是是,則把正在編輯的內容提交到內存
cdsRecord.Post;
cdsRecord.ApplyUpdates(0); //提交cdsRecord數據集到數據庫,參數0表示遇到提交異常則返回,若是你能容忍某一條記錄提交失敗仍然能夠執行下一條的,那麼能夠填寫你的容忍值
這裏要注意,DataSetProvider的UpdateMode要設置爲upWhereKeyOnly,並在cdsRecord的主鍵(或其餘不被修改的字段)的ProviderFlags的pfInKey設置爲true。
在cdsRecordAfterApplyUpdates中提交日誌
//提交後記錄提交日誌 if adqLog.State in [ dsEdit, dsInsert] then adqLog.Post; adqLog.UpdateBatch(arAll);//這裏是ADOQuery的一個批量上傳選項
ClientDataSet增長一條記錄
cdsRecord.AppendRecord(['7008','1982',false,false,'2018-06-28 19:19:26','','7993','PM','1000495']);
若是須要在ClientDataSet中處理SQL或生成字段信息,那麼能夠在ClientDataSet的CommandText處理,但前提是要在DataSetProvider的Options中設置poAllowCommandText爲true。
待續......