为什么Query.Open后的数据集是Readonly?怎样才能使Query处于编辑状态? 可以用query加updatesql一起用,又可以查询,又可以修改,还能增加与删除。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 把query的requestlive高为true也可以的。 还是用Query吧!Table的Filter功能很弱!前面两位说得很对! 我怎么设置UpdateSQL的属性?以前我从未用过UpdateSQL,我数据库是Oracle,用BDE连接!Query.RequestLive:=True;Query.CachedUpdate:=True;Query.UpdateObject:=UpdateSql1;后面怎么办? Query.RequestLive:=True;Query.CachedUpdate:=false;Query.UpdateObject:=UpdateSql1;这样跟table控件用起来就没什么两样了,如果把CachedUpdate:=true,post之后还得提交才行。 用了UpdateSql之后,Query1.RequestLive:=True /False都没所谓。 ylk_pop(贪食蛇) :如果Query1.RequestLive:=False的话是不能修改的啊。我给你帖段文章吧,这问题到今天我才真正解决。建議你多使用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;interfaceuses 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;implementationuses Unit2;{$R *.DFM}procedure TForm1.Button2Click(Sender: TObject);beginDM.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;interfaceuses 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.注:我是用一个按纽来保存修改结果的,procedure TForm1.SpeedButton22Click(Sender: TObject);begintable1.Close;table1.active:=false;query1.open;query1.cachedupdates:=true;Query1.applyUpdates;Query1.CommitUpdates;query1.cachedupdates:=false;end;另外还有:procedure TForm1.Query1UpdateRecord(DataSet: TDataSet; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);beginif Table1.Tablename='zhiwubiandon' thenbegintable1.close;table1.active:=false;query1.updateobject:=updatesql2;updatesql2.setparams(updatekind);updatesql2.ExecSQL(updatekind);updateaction:=uaappliedend;if table1.tablename='kaohe' thenbegintable1.close;table1.active:=false;query1.updateobject:=updatesql1;updatesql1.setparams(updatekind);updatesql1.ExecSQL(updatekind);updateaction:=uaapplied;end;end;你自己看着改改吧,记住不要把query1.cachedupdates先设为true,在保存按纽中再设。Query1.RequestLive:=True 其它和这文章一样 To: chenjiong(准程序员) 用了UpdateSql之后,Query1.RequestLive:=True /False都没所谓。 我这句话的前提是CachedUpdates:=true;我一直都是这样用的,没有问题的。你对编程的态度正是我所欣赏的。另外,对结果的保存这一点上我建议你应加入事务和异常处理(尤其是有Master/Detail的情况)。Database1.StartTransaction;try qryMaster.ApplyUpdates; qryDetail.ApplyUpdates; Database1.Commit; except qryDetail.CancelUpdates; qryMaster.CancelUpdates; Database1.RollBack; MessageDlg('你提交的数据有错!',mtError,[mbOk],0);end; qryMaster.commitUpdates; qrydetail.commitupdates;谢谢! To: chenjiong(准程序员) 对你再一次表示感谢。你上面的资料真的对我有很大的帮助。有空交个朋友:[email protected] 若你要查出某年月所有记录,采用Ttable的filter属性,可如下写:table1.open;table1.filter:='filedname='+''''+datetostr(你要查询的时间,属于Tdatetime型的)+'''';table1.filter:=true; Tangyisichuan 用QUERY组件怎么实现你上述的功能呀! twebbrowser调用URL后,帐号二次登录,变成同一个帐号的内容了 FastReport 報表分組打印問題 为什么每次都要重新打开project manager窗口 用ADO连接SQL SERVER数据库问题 有关窗体 在Delhi中使用什么控件就可以实现tcp,udp? 关于“流” button如何触发PageControlChange事件? Data2000 v1.1正式发布(想要1157条delphi代码吗?) !!!!第三方控件的使用方法??????? 数据导出问题: 请问怎样打包第三方控件!
前面两位说得很对!
我数据库是Oracle,用BDE连接!
Query.RequestLive:=True;
Query.CachedUpdate:=True;
Query.UpdateObject:=UpdateSql1;
后面怎么办?
Query.CachedUpdate:=false;
Query.UpdateObject:=UpdateSql1;
这样跟table控件用起来就没什么两样了,如果把CachedUpdate:=true,post之后还得提交才行。
我给你帖段文章吧,这问题到今天我才真正解决。建議你多使用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;
interfaceuses 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.
注:我是用一个按纽来保存修改结果的,
procedure TForm1.SpeedButton22Click(Sender: TObject);
begin
table1.Close;
table1.active:=false;
query1.open;
query1.cachedupdates:=true;
Query1.applyUpdates;
Query1.CommitUpdates;
query1.cachedupdates:=false;
end;
另外还有:
procedure TForm1.Query1UpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
if Table1.Tablename='zhiwubiandon' then
begin
table1.close;
table1.active:=false;
query1.updateobject:=updatesql2;
updatesql2.setparams(updatekind);
updatesql2.ExecSQL(updatekind);
updateaction:=uaapplied
end;
if table1.tablename='kaohe' then
begin
table1.close;
table1.active:=false;
query1.updateobject:=updatesql1;
updatesql1.setparams(updatekind);
updatesql1.ExecSQL(updatekind);
updateaction:=uaapplied;
end;
end;你自己看着改改吧,记住不要把query1.cachedupdates先设为true,在保存按纽中再设。
Query1.RequestLive:=True 其它和这文章一样
用了UpdateSql之后,Query1.RequestLive:=True /False都没所谓。
我这句话的前提是CachedUpdates:=true;
我一直都是这样用的,没有问题的。
你对编程的态度正是我所欣赏的。
另外,对结果的保存这一点上我建议你应加入事务和异常处理(尤其是有Master/Detail的情况)。
Database1.StartTransaction;
try
qryMaster.ApplyUpdates;
qryDetail.ApplyUpdates;
Database1.Commit;
except
qryDetail.CancelUpdates;
qryMaster.CancelUpdates;
Database1.RollBack;
MessageDlg('你提交的数据有错!',mtError,[mbOk],0);
end;
qryMaster.commitUpdates;
qrydetail.commitupdates;
谢谢!
对你再一次表示感谢。
你上面的资料真的对我有很大的帮助。
有空交个朋友:[email protected]
table1.open;
table1.filter:='filedname='+''''+datetostr(你要查询的时间,属于Tdatetime型的)+'''';
table1.filter:=true;
用QUERY组件怎么实现你上述的功能呀!