日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

ClientDataSet的用法(轉(zhuǎn)) - CNQCJ 的Delphi 博客 - 博客園

 遠(yuǎn)在南非 2010-07-09

ClientDataSet的用法(轉(zhuǎn))


TClientDataSet控件繼承自TDataSet,其數(shù)據(jù)存儲文件格式擴展名為 .cds,是基于文件型數(shù)據(jù)存儲和操作的控件。該控件封裝了對數(shù)據(jù)進行操作處理的接口和功能,而本身并不依賴上述幾種數(shù)據(jù)庫驅(qū)動程序,基本上能滿足單機"瘦"數(shù)據(jù)庫應(yīng)用程序的需要。

  1.TClientDataSet的基本屬性和方法介紹

  1).FieldDefs: 字段定義列表屬性

  開發(fā)者可通過單擊屬性編輯器中該屬性編輯按鈕,或在該控件上單擊右鍵選擇彈出菜單中的"Fields Editor"菜單進行字段編輯。設(shè)置完此屬性后,實際上就相當(dāng)于定義了表的結(jié)構(gòu);如果想裝入已有的數(shù)據(jù)表的結(jié)構(gòu)和數(shù)據(jù),可通過單擊右鍵選擇彈出菜單中的"Assign Local Data"菜單,從彈出對話框中選取當(dāng)前窗體中已與數(shù)據(jù)庫連接好的數(shù)據(jù)集控件名稱即可(當(dāng)前窗體中必須已放置好要套用的數(shù)據(jù)集控件并打開激活)。

  使用注意:

  對于自定義的字段名表,該屬性編輯完后,該控件仍然無法打開。必須右鍵單擊該控件,選擇彈出菜單中的"Create DataSet"菜單,讓該控件以上述編輯的字段列表為依據(jù),創(chuàng)建數(shù)據(jù)集后,才能夠被激活打開和使用。否則,會出現(xiàn)類似"ClientDataSet1: Missing data provider or data packet."的錯誤(包括在運行期,運行期可調(diào)用該控件的CreateDataSet方法,從而動態(tài)定義字段和表)。
2).FileName屬性

  說明:數(shù)據(jù)存儲文件的名稱。

  因該控件是基于文件型的數(shù)據(jù)操作控件,因此,必須指定所操作的數(shù)據(jù)文件名稱(默認(rèn)擴展名稱.cds),從而打開和激活該控件,進而進行數(shù)據(jù)編輯。

  例1:利用此屬性打開指定的.cds文件

var
Path: string;
begin
 Path := ExtractFilePath(Application.ExeName); //取得可執(zhí)行文件路徑
 CDataSet1.FileName := Path + 'test.cds';
 CDataSet1.Open;
end;

  3).CreateDataSet方法

  說明:該方法以FieldDefs中的字段名表為結(jié)構(gòu)建立數(shù)據(jù)集,常用來進行動態(tài)定義表。

  例2:動態(tài)創(chuàng)建一具有姓名和年齡兩個字段的數(shù)據(jù)集。

//創(chuàng)建字段名表
CDataSet.FieldDefs.Clear;
with CDataSet.FieldDefs.AddFieldDef do
begin
 Name := 'Name';
 Size := 10;
 DataType := ftString;
end;
with CDataSet.FieldDefs.AddFieldDef do
begin
 Name := 'Age';
 DataType := ftInteger;
end;
 //動態(tài)創(chuàng)建數(shù)據(jù)集
 CDataSet.CreateDataSet;
 //激活和打開該數(shù)據(jù)集
 CDataSet.Open;

  4).Open方法

  說明: 打開和激活數(shù)據(jù)集控件,從而進行數(shù)據(jù)編輯。

  a. 如果指定了FileName屬性,則直接用Open方法即可打開和激活該控件,見例1。

  b. 如果未指定FileName屬性,可使用例2方法動態(tài)創(chuàng)建和打開數(shù)據(jù)集,進而操作數(shù)據(jù)。

  5).LoadFromFile和SaveToFile

  說明:從文件中裝入表結(jié)構(gòu)和數(shù)據(jù)以及存儲數(shù)據(jù)到文件。該方法類似于Word中的打開新文件和另存為的功能。

  例3:將數(shù)據(jù)集的數(shù)據(jù)存儲到指定文件中

CDataSet.SaveToFile('c:\windows\desktop\test.cds');

  6).First(到首),Prior(向前),Next(向后),Last(到尾),Edit(編輯),CanCel(取消編輯),Post(保存),Insert(插入記錄),Append(添加記錄),Delete(刪除),Refresh(數(shù)據(jù)刷新)等數(shù)據(jù)集常用方法

  說明:當(dāng)指定了FileName屬性時,其Post方法可將數(shù)據(jù)存入指定的文件中,類似其SaveToFile方法;如果未指定存儲文件名,則Post方法只將數(shù)據(jù)存儲在RAM中。其它方法,同一般數(shù)據(jù)集控件使用方法,略。

  7).Filter, Filtered: 過濾篩選屬性

  說明:用于篩選指定條件的記錄,用法同一般數(shù)據(jù)集控件,略。

  例4:在已經(jīng)激活打開的數(shù)據(jù)集中篩選性別為男性的記錄

CDataSet.Close;
CDataSet.Filter := '性別=''' + '男' + '''';
CDataSet.Filtered := True;
CDataSet.Open;

  2.使用TClientDataSet控件的應(yīng)用程序發(fā)布的注意事項:

  如前所述,使用TClientDataSet控件的程序發(fā)布時不需要任何數(shù)據(jù)庫驅(qū)動程序,大大節(jié)省了安裝文件的大小。但是,在發(fā)布程序時別忘了將Windows系統(tǒng)目錄下midas.dll(257KB)與應(yīng)用程序一起發(fā)布(運行必須),否則,程序仍然無法正常運行。

  三、結(jié)束語

  通過使用Delphi中TClientDataSet控件,既實現(xiàn)了應(yīng)用程序可徹底脫離數(shù)據(jù)庫驅(qū)動程序,也實現(xiàn)了常規(guī)數(shù)據(jù)集控件簡單易用的特性,為編寫"瘦"數(shù)據(jù)庫應(yīng)用程序提供了一種技術(shù)方法和手段。

  上述程序在Pwindows98,Delphi5下測試通過。


     TClientDataSet在三層結(jié)構(gòu)中,TClientDataSet的地位是不可估量的,她的使用正確與否,是十分關(guān)鍵的,本文從以下幾個方面闡述她的使用,希望對你有所幫助.
1.動態(tài)索引
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
if (not column.Field is Tblobfield) then//Tblobfield不能索引,二進制
ClientDataSet1.IndexFieldNames:=column.Field.FieldName;
end;
2.多層結(jié)構(gòu)中主從表的實現(xiàn)
設(shè)主表ClientDataSet1.packetrecord為-1,所有記錄
設(shè)從表ClientDataSet1.packetrecord為0,當(dāng)前記錄
3.Taggregates使用
(1)在字段編輯中add new field類型為aggregates
     后設(shè)置expression(表達試)
     設(shè)置active:=true即可
     使用dbedit的field為前者即可
(2)使用Aggergates屬性add設(shè)計表達試
    調(diào)用
  showmessage(floattostr(ClientDataSet1.Aggregates.Count));
  showmessage(ClientDataSet1.Aggregates.Items[0].Value);

4.在單層數(shù)據(jù)庫中不要BDE
  使用ClientDataSet代替table,使用ClientDataSet的loadfilename裝入cds
  代替table的tablename的db或者dbf
  原來的程序改造方法:
  加一個ClientDataSet,使用右鍵assign locate data
  后savetofile,再loadfromfile,后刪除table
  將原連table的datasource設(shè)為ClientDataSet
  唯一注意的是:要將midas.dll拷到system或者當(dāng)前目錄
5.三層結(jié)構(gòu)的公文包的實現(xiàn)方法
 同時設(shè)定1:filename(*.cds)2.remote server
6.可以對data賦值(從另一個數(shù)據(jù)集取值)
 ClientDataSet2.Data:=ClientDataSet1.Data;
 ClientDataSet2.Open;
 或者
 ClientDataSet2.CloneCursor(ClientDataSet1,true);
 ClientDataSet2.Open;
7.附加數(shù)據(jù)取得
  客戶程序向應(yīng)用服務(wù)器請求數(shù)據(jù)。如果TClientDataSet 的
  FetchOnDemand 屬性設(shè)為True,
  客戶程序會根據(jù)需要自動檢索附加的數(shù)據(jù)包如BLOB字段的值或嵌套表的內(nèi)容。
  否則,
  客戶程序需要顯式地調(diào)用GetNextPacket 才能獲得這些附加的數(shù)據(jù)包。
  ClientDataSet的packetrecords設(shè)置一次取得的記錄個數(shù)
8.ClientDataSet與服務(wù)器端query連接方法
  (1)sql內(nèi)容為空
     ClientDataSet1.Close;
     ClientDataSet1.CommandText:=edit1.Text;//即sql內(nèi)容
     ClientDataSet1.Open;
   對于沒有應(yīng)用服務(wù)器設(shè)置filter 如:country like 'A%'
   filtered=true可實現(xiàn)sql功能
  (2)有參數(shù)
   如服務(wù)端query的sql為
    select * from animals 
    where name like :dd
   則:客戶端ClientDataSet
   var
   pm:Tparam;
  begin
     ClientDataSet1.Close;
     ClientDataSet1.ProviderName:='DataSetProvider1';
     pm:=Tparam.Create(nil);
     pm.Name:='dd';
     pm.DataType:=ftString;
     ClientDataSet1.Params.Clear;
     ClientDataSet1.Params.AddParam(pm);
     ClientDataSet1.Params.ParamByName('dd').AsString:=edit1.Text ;
     ClientDataSet1.Open;
     pm.Free;
  end;

9.數(shù)據(jù)的更新管理
  (1)savepoint 保存目前為止數(shù)據(jù)狀態(tài),可以恢復(fù)到這個狀態(tài)
  var
    pp:integer;
  begin
     pp:=ClientDataSet1.SavePoint;
     ClientDataSet1.Edit;
     ClientDataSet1.FieldByName('姓名').asstring:='古話';
     ClientDataSet1.Post;
     table1.Refresh;
   end;
  恢復(fù)點
    ClientDataSet1.SavePoint:=pp;
  (2)cancel,RevertRecord
       取消對當(dāng)前記錄的修改,只適合沒有post的,如果post,調(diào)用
   RevertRecord
   (3)cancelupdate
    取消對數(shù)據(jù)庫所有的修改
  (4)UndoLastChange(boolean),changecount
    取消上一次的修改,可以實現(xiàn)連續(xù)撤消
    參數(shù)為true:光標(biāo)到恢復(fù)處
          false:光標(biāo)在當(dāng)前位置不動
   changecount返回修改記錄的次數(shù),一個記錄修改多次,返回只一次
   但UndoLastChange只撤消一次
   
10.可寫的recno
   對于Ttable和Tquery的recno是只讀的,而TClientDataSet的recno可讀可寫
   ClientDataSet1.recno:=5;是設(shè)第五個記錄為當(dāng)前記錄
11.數(shù)據(jù)保存
  對于table使用post可更新數(shù)據(jù)
  而ClientDataSet1的post只更新內(nèi)存數(shù)據(jù),要更新服務(wù)器數(shù)據(jù)要使用
  ApplyUpdates(MaxErrors: Integer),他有一個參數(shù),是允許發(fā)出錯誤的
  次數(shù),-1表示無數(shù)次,使用simpleobjectbroker時常設(shè)為0,實現(xiàn)自動容錯和負(fù)載平衡

====================================================== 

影響ClientDataSet處理速度的一個因素
TClientDataSet是Delphi開發(fā)數(shù)據(jù)庫時一個非常好的控件。有很強大的功能。
我常常用ClientDataSet做MemoryDataSet來使用。還可以將ClientDataSet的數(shù)據(jù)保存為XML,這樣就可以做簡單的本地數(shù)據(jù)庫使用。還有很多功能就不多說了。在使用ClientDataSet的過程中關(guān)于怎樣提高處理速度這個問題,我就我個人的一點點體會和大家分享一下。

通常情況下我們一般都是用
...ClientDataSet-->DataSource-->DBComponent
這樣的結(jié)構(gòu),處理數(shù)據(jù)的時候就直接操作ClientDataSet。但是大多DBComponet都會立即響應(yīng)ClientDataSet的變化。如果你是向ClientDataSet中插入很多數(shù)據(jù)時候,DBComponent就要響應(yīng)幾次,而且響應(yīng)過程根據(jù)不同的控件,速度,過程數(shù)量都不一樣。這樣就影響了程序的執(zhí)行效率。所以在對ClientDataSet處理中,我是用ClientDataSet.DisableControls和ClientDataSet.EnableControls方法:打開和關(guān)閉DBComponent與ClientDataSet的數(shù)據(jù)顯示關(guān)系。
例如:
ClientDataSet..DisableControls;
...
for I := 0 to 10000 do
begin
ClientDataSet.Append;
...
ClientDataSet.Post;
end;
...
ClientDataSet.EnableControls
...
這樣做以后你會發(fā)現(xiàn)處理速度比以前沒有使用方法的時候有成倍的提高。 
 
ClientDataSet的數(shù)據(jù)查找。
我所介紹的心得和技巧都是用ClientDataSet來做范例,也可以應(yīng)用于其他的一些DataSet。廢話就不多說了。我們還是先看代碼,讓后再總結(jié)。
1.Scanning 掃描數(shù)據(jù)查找
這是最簡單最直接也是最慢的一種方法,遍歷所有數(shù)據(jù):
procedure TForm1.ScanBtnClick(Sender: TObject);
var
  Found: Boolean;
begin
Found := False;
ClientDataSet1.DisableControls;
Start;
try
  ClientDataSet1.First;
  while not ClientDataSet1.Eof do
  begin
    if ClientDataSet1.Fields[FieldListComboBox.ItemIndex].value =
      SearchText then
      begin
        Found := True;
        Break;
      end;
    ClientDataSet1.Next;
  end;
Done;
finally
  ClientDataSet1.EnableControls;
end;
if Found then ShowMessage(SearchText +
  ' found at record ' + IntToStr(ClientDataSet1.RecNo))
else
  ShowMessage(ScanForEdit.Text + ' not found');
end;

2.Finding 尋找數(shù)據(jù)
最老,但是最快的查找方式。
使用FindKey/FindNearest來查找一條或多條符合條件的數(shù)據(jù),當(dāng)然待查找的Field必須是一個IndexField??梢钥闯觯@種基于Index的查找速度是非??斓?。
procedure TForm1.FindKeyBtnClick(Sender: 
TObject);
begin
Start;
if ClientDataSet1.FindKey([SearchText]) then
begin
  Done;
  StatusBar1.Panels[3].Text := SearchText +
    ' found at record ' +
    IntToStr(ClientDataSet1.RecNo);
end
else
begin
  Done;
  StatusBar1.Panels[3].Text :=
    SearchText + ' not found';
end;
end;

procedure TForm1.FindNearestBtnClick(Sender: TObject);
begin
Start;
ClientDataSet1.FindNearest([SearchText]);
Done;
StatusBar1.Panels[3].Text := 'The nearest match to ' +
  SearchText + ' found at record ' +
  IntToStr(ClientDataSet1.RecNo);
end

3.Going 定位
GotoKey/GotoNearest 與FindKey/FindNearest基本上沒有什么區(qū)別。它也是基于Index的查找。唯一的區(qū)別就是在于你是怎么定義你的查找了。代碼上也有區(qū)別:
ClientDataSet1.SetKey;
ClientDataSet1.FieldByName(IndexFieldName).value := SearchText;
ClientDataSet1.GotoKey;
就相當(dāng)于
ClientDataSet1.FindKey([SearchText]);
要用好這兩種基于Index的查找,還需要了解ClientDataSet和Index機制。這里就不詳細(xì)說明Index機制。一個基本的原則,要有Index,才能查找。

4.Locating 查找數(shù)據(jù)
2,3兩種查找方式都是基于Index的,但是在實際應(yīng)用中,可能會查找IndexField以外的Field。那我們就可以使用Locate。但是查找速度是沒有2,3兩種快的。比如:如果你查找一條紀(jì)錄9000/10000,Locate需要500ms,Scanning需要>2s,F(xiàn)indKey只要10ms(但是當(dāng)你打開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;


小結(jié):
ClientDataSet提供了好多種查找數(shù)據(jù)的方法。但是各自有其優(yōu)缺點。
上面的例子中有Start;和Done,如果你有興趣,可以加入計時點進行速度測試。
Scanning最簡單,但是最慢,因為比較慢,還得使用ClientDataSet.DisableControls和ClientDataSet.EnableControls方法(我在前面一片文章講過)。
Findkey/FindNearest(GotoKey/GotoNearest)代碼多,但是非常快。必須使用Index,不同的是Find需要的Index是必須建立好的,而Goto可以在第一次使用時建立Index。
Locate使用最方便,不需要Index,但是速度沒有Find快。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多