看的人不多,我再加20分。最好能有demo包。不用急的,想好了明天答也行的,我等着。请讲详细点。

解决方案 »

  1.   

    其实我也没有用增加,只是能完成修改就行了。我用的是.db数据库,高手们给我讲讲详细的过程吧!就连query1.updateerror应如何处理也讲讲。最好是能做一demo包,那样详细的多。还有,我是对用sql查询出的单条或多条记录进行修改。
      

  2.   

    有必要动态指定query的updateSQL对象吗?如没必要,设计时指定。如必须动态指定,query1.updateobject:=updatesql1;后还要设定updateSQL的DeleteSQL、InsertSQL、ModifySQL属性,他们对应的是三句SQL语句:Insert、Delete、Update语句,你的明白?在UpdateError过程中可以得到错误代码,可以根据不同的错误代码给出相应的中文提示。
    procedure TFcard.QcardUpdateError(DataSet: TDataSet; E: EDatabaseError;
      UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
    var
      Temp : String;
    begin
      inherited;
      if (E is EDBEngineError) then
      begin
        if (E as EDBEngineError).Errors[0].Errorcode = 9729 then
        begin
          messagebox(handle,'关键字重复','警告',mb_ok);
        end
        else if (E as EDBEngineError).Errors[0].Errorcode = 9732 then
        begin
          messagebox(handle,'字段值不能为空','警告',mb_ok);
        end
        else if (E as EDBEngineError).Errors[0].Errorcode = 13059 then
        begin
          messagebox(handle,'关键字不能为空','警告',mb_ok);
        end
        else if (E as EDBEngineError).Errors[0].Errorcode = 9733  then
        begin
           Temp := copy((E as EDBEngineError).message,25,1);
           if temp = 'D' then
              messagebox(handle,'子表记录存在!不允许删除!','警告',mb_ok);
           if temp = 'U' then
              messagebox(handle,'子表记录存在!不允许修改!','警告',mb_ok);
        end else messagebox(handle,'提交数据时出现错误,请重试','警告',mb_ok);
      end else messagebox(handle,'提交数据时出现错误,请重试','警告',mb_ok);
    end;
      

  3.   

    我的明白!对于我来说,现在并不要动态指定updatesql对象,我也没去搞这东西。我只要能修改就行了,也就是ModifySQL属性设置就可以了。现在又来了,要么是“table is read only”要么是“query is not edit or insert mode”不过确定后数据实际上是已经提交了的,修改是成功的。什么原因?在保存的按纽事件中写:
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    Query1.applyUpdates;
    Query1.CommitUpdates;在
    procedure TDM.Query1UpdateRecord(DataSet: TDataSet;
      UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
    begin
    Updatesql1.SetParams(UpdateKind);
    Updatesql1.ExecSQL(UpdateKind);
      
    end;end;
      

  4.   

    Query所对应的Datasource的AutoEdit属性设为true;
      

  5.   

    对啊,我原来就是这样设的。目前主要是“table is read only”,而且按确定后数据虽然能提交,但只能提交第一次的改动记录,不能全部提交。还有,运行程序,执行查询后程序目录里总会出来一个什么del8.mb的东西,这是什么?
      

  6.   

    想想暂时没得问,wangxd1976(西门吹雪):先欠你20分吧,下回我问了问题,叫大家都来这挂号拿分,一起结帐行不?
      

  7.   

    不知你如何解决“Table is read only"的问题?
    我也正遇到这个!
    为什么第一次写不行,(乱搞乱搞就行了,不会没改程序吧?)?
    ==============
    如果,不用Query1.Apply等,
    直接用Updatesql1.SetParams(UpdateKind); Updatesql1.ExecSQL(UpdateKind);
    到没问题。
    用Query1.Apply  时其中SQL语言不执行了,是吗?
      
      

  8.   

    不明白为什么要在这里加一贴。
    这里是回复你
    http://www.csdn.net/expert/Topic/133/133300.shtm的:edit1.Text:=DBGrid1.SelectedField.AsString 
    ONDbClick 
      

  9.   

    xuehao() :当时代码没错,是有些字段的记录为空的原因。“table is read only”是由于table1还控制着.db,没有用query代替的原因。我帖篇文章给你看看,照上面的做就行了。利用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;
    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.插入可直接用insert,删除用del...,和table中的一样的。不行的话和我联系:
    [email protected]