打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
利用CachedUpdates功能和TUpdateSQL件來更新多個資料表產生的查詢結果 ...
利用CachedUpdates功能和TUpdateSQL件來

更新多個資料表產生的查詢結果

(by WilliamGui)



建議你多使用TQuery元件來撰寫程式﹐你除了可以利用TQuery下達SQL的查詢命令外﹐你也可以利用TQuery元件來進行新增﹑修改﹑刪除資料的動作﹐你不但可以直接下新增﹑修改﹑刪除的SQL命令﹐Delphi還允許你直接修改 TQuery查詢產生的DataSet內容﹐然后再寫回資料庫﹐這就是Delphi所謂 LiveData的功能。你只要把TQuery元件的RequestLive屬性設成True﹐你就修改查詢產生的DataSet資料﹐并且將其寫回資料庫內。



可是TQuery的RequestLive功能只允許一次對應到一個資料表﹐換句話說﹐如果 Tquery內的SQL命令包含超過一個以上的資料表時﹐所產生的DataSet將會是一個唯讀的資料集﹐如果你硬是要把此TQuery的RequsetLive設成 True﹐那么你將會得到一個"Table is read only. "的錯誤訊息。



Delphi允許你把Query1先設成CachedUpdates﹐然后再利用TUpdateSQL元件一個一個把Query1內異動到的資料表更新到資料庫內﹐這里就以一個實際的范例來說明程式的寫法。首先﹐請先拖拉一個TQuery元件到DataModule上﹐把DatabaseName指向IBLOCAL﹐并且在Query1的SQL屬性內撰寫下列SQL命令﹕



Select Distinct d.dept_no, d.department, d.phone_no, e.emp_no, e.first_name,

       e.last_name, e.phone_ext, e.salary

       from department d,employee e where(e.dept_no=d.dept_no)

       order by d.dept_no, d.department, d.phone_no, e.emp_no, e.first_name,

                e.last_name, e.phone_ext, e.salary



因為上列這串SQL查詢命令會牽涉到IBLOCAL的DEPARTMENT和EMPLOYEE這兩個資料表﹐所以如果你想修改查詢出來的結果(DataSet)﹐你就必須把Query1的屬性CachedUpdates設成True﹐以及把RequestLive屬性也設成True ﹐然后再拖拉兩個TUpdateSQL元件到DataModule上﹐分別設定其名稱為UpdateDepartment及UpdateEmployee。



首先﹐請先把Query1的UpdateObject屬性設成UpdateDepartment﹐接著連續點選UpdateDepartment二下開啟UpdateSQL的編輯器﹐你可以把DEPARTMENT資料表指定給這個元件﹐然后選出你想要Update的資料欄位﹐最后點選[Generate SQL]功能按鈕﹐TUpdateSQL元件將會自動幫你產生Update的SQL命令﹐只要再點選[SQL]頁次﹐你就可以看到那些SQL命令。



接下來﹐請你把Query1的UpdateObject屬性改成UpdateEmployee﹐然后開啟UpdateEmployee的UpdateSQL編輯器重復上述的步驟﹐讓UpdateEmployee可以自動產生Update用的SQL命令。建立上述兩個UpdateSQL元件的目的就是為了分別Update在Query1使用到的DEPARTMENT及EMPLOYEE資料表﹐而這些動作必須依賴QUERY1產生的DataSet 來進行﹐這也是為什么我們要把DataSet設在BDE的Cached Buffer里面。因為如此一來﹐你才能各個擊破地分別把每個資料表的異動資料寫回到資料庫中。



當你把Query1的屬性CachedUpdates設成True之后﹐任何針對Query1產生的DataSet異動的結果都會被記錄在前端BDE的Cached Buffer內﹐只有執行Query1.ApplyUpdates命令時﹐這些存放在BDE Cached Buffer內的所有異動資料才會被寫入資料庫中。當BDE把Buffer內的異動記錄一筆一筆地寫到資料庫時﹐每寫入一筆就會去呼叫Query1的OnUpdateRecord事件程序一次﹐這時候﹐你就可以把Update每個資料表的程式寫在這個事件程序內﹐如下所示﹕



procedure TDM.Query1UpdateRecord(DataSet:TDataSet; UpdateKind:TUpdateKind; var UpdateAction:TUpdateAction);

begin

  //先把Employee的異動記錄寫回資料庫內

  DM.Query1.UpdateObject:=UpdateEmployee;

  UpdateEmployee.SetParams(UpdateKind);

  UpdateEmployee.ExecSQL(UpdateKind);

  //再把Department的異動記錄寫回資料庫內

  DM.Query1.UpdateObject:=UpdateDepartment;

  UpdateEmployee.SetParams(UpdateKind);

  UpdateEmployee.ExecSQL(UpdateKind);

  UpdateAction:=uaApplied;

end;



整個同時更新多個資料表的范例程式最重要的程式就是上面這段程式﹐其它部分的詳細內容請你參考下面程式說明。



program Project1;

uses

  Forms,

  Unit1 in 'Unit1.pas' {Form1},

  Unit2 in 'Unit2.pas' {DM: TDataModule};

{$R *.RES}

begin

  Application.Initialize;

  Application.CreateForm(TDM, DM);

  Application.CreateForm(TForm1, Form1);

  Application.Run;

end.



unit Unit1;

interface

uses

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

  StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, Db;

type

  TForm1 = class(TForm)

    DBGrid1: TDBGrid;

    DBNavigator1: TDBNavigator;

    Button1: TButton;

    Button2: TButton;

    Button3: TButton;

    DataSource1: TDataSource;

    procedure Button2Click(Sender: TObject);

    procedure FormCreate(Sender: TObject);

    procedure Button3Click(Sender: TObject);

    procedure Button1Click(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

var

  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button2Click(Sender: TObject);

begin

DM.Query1.applyUpdates;

DM.Query1.CommitUpdates;

ShowMessage('Update 成功!');

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

  DM.Query1.Close;

  DM.Query1.CachedUpdates:=True;

  DM.Query1.RequestLive:=true;

  Dm.Query1.open;

end;

procedure TForm1.Button3Click(Sender: TObject);

begin

    FormCreate(nil);

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

    DM.Query1.CancelUpdates;

end;

end.



unit Unit2;

interface

uses

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

  Db, DBTables;

type

  TDM = class(TDataModule)

    Query1: TQuery;

    UpdateDepartment: TUpdateSQL;

    UpdateEmployee: TUpdateSQL;

    Database1: TDatabase;

    procedure Query1UpdateRecord(DataSet: TDataSet;

      UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

var

  DM: TDM;

implementation

{$R *.DFM}

procedure TDM.Query1UpdateRecord(DataSet: TDataSet;

  UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

  //先把Employee的異動記錄寫回資料庫內

  DM.Query1.UpdateObject:=UpdateEmployee;

  UpdateEmployee.SetParams(UpdateKind);

  UpdateEmployee.ExecSQL(UpdateKind);

  //再把Department的異動記錄寫回資料庫內

  DM.Query1.UpdateObject:=UpdateDepartment;

  UpdateEmployee.SetParams(UpdateKind);

  UpdateEmployee.ExecSQL(UpdateKind);

  UpdateAction:=uaApplied;

end;

end.
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
delphi
SQL /数据库 使用蓝皮书 大富翁论坛-富翁笔记-
Delphi中实现多线程同步查询
dataset如何批量更新添加数据库
Delphi数据库开发之TBDEDataSet.CachedUpdates
oracle function返回结果集
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服