DELPHI 數據庫心得

 

TField對象的SetText和GetText事件處理函數

使用TField對象的SetText和GetText事件處理函數可方便的解決字段的代碼與代碼所對應值的顯示問題

 

TSimpleDataset/TClientDataset對象的Aggregation

使用TDataset對象的Aggregate屬性可以來計算客戶端數據集中數據的總計數值、平均值或是計算最大值和最小值。

 

使用TBookMark來標記記錄書籤, 訪問數據集中的數據

通過使用TBookMark以及TDataset對象的 BookMark 屬性, 要以爲當前的紀錄設置書籤,

var

  bk:TBookMark;

begin

  bk:=ds.GetBookMark; //設置書籤

  ....

  ds.GoToBookMark(bk);//回到原來的紀錄

  ds.FreeBookMark(bk);//釋放內存

end;

 

Locate 與 Lookup 區別:

Locate找到查尋的數據後,它會把目前的記錄位置移動到找到的這筆數據上

Lookup找到查尋的數據後,它會回傳找到的數據的特定字段數值,卻不會移動目前的記錄位置。

Lookup方法的第三個參數則是指定當Lookup找到欲查尋的數據之後,要回傳這筆數據的那些字段數值。如果開發人員想要Lookup回傳多個字段數值,那麼每一個字段也是以分號分隔。

至於Lookup方法回傳的數值則是第三個字段指定的字段數值,如果Lookup回傳多個字段的話,那麼這個回傳數值就是一個Variant數組,每一個回傳的字段便儲存在這個Variant數組的元素之中。

例:

 

 

 

ClientDataSet使用心得和技巧

 

影響ClientDataSet處理速度的一個因素

TClientDataSet是Delphi開發數據庫時一個非常好的控件。有很強大的功能。

我常常用ClientDataSet做MemoryDataSet來使用。還可以將ClientDataSet的數據保存爲XML,這樣就可以做簡單的本地數據庫使用。還有很多功能就不多說了。在使用ClientDataSet的過程中關於怎樣提高處理速度這個問題,我就我個人的一點點體會和大家分享一下。

通常情況下我們一般都是用

...ClientDataSet-->DataSource-->DBComponent

這樣的結構,處理數據的時候就直接操作ClientDataSet。但是大多DBComponet都會立即響應ClientDataSet的變化。如果你是向ClientDataSet中插入很多數據時候,DBComponent就要響應幾次,而且響應過程根據不同的控件,速度,過程數量都不一樣。這樣就影響了程序的執行效率。所以在對ClientDataSet處理中,我是用ClientDataSet.DisableControls和ClientDataSet.EnableControls方法:打開和關閉DBComponent與ClientDataSet的數據顯示關係。

例如:

ClientDataSet..DisableControls;

...

for I := 0 to 10000 do

begin

  ClientDataSet.Append;

  ...

  ClientDataSet.Post;

end;

...

ClientDataSet.EnableControls

...

這樣做以後你會發現處理速度比以前沒有使用方法的時候有成倍的提高。

 

ClientDataSet的數據查找。

我所介紹的心得和技巧都是用ClientDataSet來做範例,也可以應用於其他的一些DataSet。廢話就不多說了。我們還是先看代碼,讓後再總結。

1.Scanning 掃描數據查找

這是最簡單最直接也是最慢的一種方法,遍歷所有數據:

 

 

2.Finding 尋找數據

最老,但是最快的查找方式。

使用FindKey/FindNearest來查找一條或多條符合條件的數據,當然待查找的Field必須是一個IndexField。可以看出,這種基於Index的查找速度是非常快的。

 

  

3.Going 定位

GotoKey/GotoNearest 與FindKey/FindNearest基本上沒有什麼區別。它也是基於Index的查找。唯一的區別就是在於你是怎麼定義你的查找了。代碼上也有區別:

ClientDataSet1.SetKey;

ClientDataSet1.FieldByName(IndexFieldName).value := SearchText;

ClientDataSet1.GotoKey;

就相當於

ClientDataSet1.FindKey([SearchText]);

要用好這兩種基於Index的查找,還需要了解ClientDataSet和Index機制。這裏就不詳細說明Index機制。一個基本的原則,要有Index,才能查找。

 

4.Locating 查找數據

2,3兩種查找方式都是基於Index的,但是在實際應用中,可能會查找IndexField以外的Field。那我們就可以使用Locate。但是查找速度是沒有2,3兩種快的。比如:如果你查找一條紀錄9000/10000,Locate需要500ms,Scanning需要>2s,FindKey只要10ms(但是當你打開ClientData的時候,建立Index需要1s)。

procedure TForm1.LocateBtnClick(Sender: TObject);

begin

  Start;

  if ClientDataSet1.Locate('Field1,Field2..',VarArrayOf['value1,value2..'], []) then

  begin

    Done;

    StatusBar1.Panels[3].Text := 'Match located at record ' + IntToStr(ClientDataSet1.RecNo);

  end

  else

  begin

    Done;

    StatusBar1.Panels[3].Text := 'No match located';

  end;

end;

 

ClientDataSet提供了好多種查找數據的方法。但是各自有其優缺點。

上面的例子中有Start;和Done,如果你有興趣,可以加入計時點進行速度測試。

Scanning最簡單,但是最慢,因爲比較慢,還得使用ClientDataSet.DisableControls和ClientDataSet.EnableControls方法(我在前面一片文章講過)。

Findkey/FindNearest(GotoKey/GotoNearest)代碼多,但是非常快。必須使用Index,不同的是Find需要的Index是必須建立好的,而Goto可以在第一次使用時建立Index。

Locate使用最方便,不需要Index,但是速度沒有Find快。

 

var

  sFields : String;

  vResult : Variant;

  iCount : Integer;

begin

  vResult := ds.Lookup('fieldnameA, fieldnameB' , VarArrayCreate([ValueA, ValueB], varVariant), 'fieldname1, fieldname2');

  if (VarIsArray(vResult)) then

  begin

      sFields := '';

      for iCount := VarArrayLowBound(vResult, 1to VarArrayHighBound(vResult,  1do

      begin

        sFields := sFields + ';' + vResult[iCount];

      end;

  end

  else

     edtReturn.Text := vResult;

end;

 

 

一些使用 DevExpress 時的小心得

 

1. 設置 DataController.Filter.AutoDataSetFilter=True 可以使過濾器直接影響後臺數據集。

2. 關於cxFormatController的一些用法。當修改了系統默認數據格式定義時,cxFormatController可通過方法 GetFormats 與 NotifyListeners 來實現刷新。

    例:

      CurrencyString := '元';

      SysUtils.CurrencyFormat := 3;

      SysUtils.CurrencyDecimals := 4;

      cxFormatController.GetFormats;

      cxFormatController.NotifyListeners;

3.更新當前所選行中某列的值,可以按以下方法實現,

Column.EditValue := AValue。如可使用 Record.Values[AIndex] := AValue, 並不能直接更新行中指定值所對應的數據集中的值。通過 Column.EditValue 剛可以實現。

 

 

TDatasetProvider.UpdateMode屬性;

upWhereAll   限制最嚴,但可以最大程度地保證記錄的一致性。如果兩個用戶編輯同一條記錄,第一個用戶能夠更新記錄,而第二個用戶將會收到“另一個用戶已經修改了這條記錄”的報錯信息。如果希望改進執行這種檢查的字段,可以去掉相應的TField.ProviderFlags屬性中的pfInWhere項。

 

upWhereChanged   實際上允許兩個用戶同時編輯一條記錄;在兩個用戶編輯同一條記錄的不同字段時,不會檢查出衝突。例如,如果用戶A修改Address字段並更新了記錄,那麼用戶B仍然能夠修改BirthDate字段併成功地更新記錄。

 

upWhereKeyOnly   限制最寬。只要是記錄存在於數據庫中,每個用戶都可以進行修改並更新。這樣,後面的修改總是覆蓋前面的修改。

系統默認的是upWhereAll,請修改爲你認爲合適的模式!

 

ADO 中處理多個返回結果集

在使用 SQL 語句時,常常會有多個結果集被返回的情況,比如 EXEC sp_helpconstraint [TableName] 就返回了兩個結果集。如果我們需要處理多個結果集時。可用ADO的 NextRecordSet 方法。用法如下:

var

  R: integer

begin

  with ADOQuery do

  begin

    Close;

    SQL.Text := 'EXEC sp_helpconstraint ' + ableName;

    Open;

    R := 0;

    Recordset := NextRecordSet(R);

    {do something }

 end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章