Delphi developed three tips: TClientDataSet of Delta Magical

When do the three Delphi development, many people will put the client in a TClientDataSet, remote data module on the intermediate layer corresponds to put a TDataSetProvider, and then put together. In fact, this method is very cumbersome, and the program carbuncles unwilling to bad maintenance. we all know that the TClientDataSet records all modifications Delta attribute data, we can use it on the convenience of a single-table updates the general method of implementation.

   First, a method of adding the intermediate layer, it is called ApplyUpdates method is defined as follows:

   function ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;

Parameters UpdateTable mean it updated table name, Delta refers to the TClientDataSet pass over the Delta property, an error is returned if the update error err content below implement this method, first put a Query on DataModule, Connection Query on even before The discharge TDataSetProvider even a Query code is as follows:

function TRoDm.ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;

const sql='select * from %s where 1<>1';

var sqlstr:string;

      ErrCount:Integer;

begin

    Result:=False;

   sqlstr:=Format(sql,[UpdateTable]);

   try

       Conn.BeginTrans;

       Query.Close;

       Query.sql.text:=sqlstr;

       Query.open;

      Provider.ApplyUpdates(Delta,-1,ErrCount);

      Result:=ErrCount=0;

      if Result then

         Conn.CommitTrans

      else Conn.RollbackTrans;

   except

       on E:Exception do

       begin

           Conn.RollbackTrans;

          err:=E.Message;

       end;

   end;

end;

    This, common method of updating has been completed but the client can not query ClientDataSet display data, therefore, you have to write a query method:

    function QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;

    Sqlstr parameter query is to hold the line, Data return query results, err returns an error message when an error

   QuerySQL codes are as follows:

function TRoDm.QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;

begin

    Result:=False;

   try

      Query.close;

      Query.sql.text:=sqlstr;

        Query.sql.Open;

        Data:=Provider.Data;

       Result:=True;

    Except

         on E:Exception do

             err:=E.Message;

    end;

end;

    Here, a code intermediate layer is done, call the client is simple. For example, the client has a data module DM, put on top of a DcomConnection or SocketConnection, named Conn. For example, we now need to do a product management function, query on the form put a TClientDataSet called Cds, put DataSource, DBGrid and so on, set the appropriate attributes and then create (create event) in the form back all the data, the code below:

const sql='select * from xxxx';

Data were Variant;

      err:String;

begin

   if Dm.Conn.AppServer.QuerySQL(sql,Data,err) then

      Cds.Data:=Data

   else MessageBox (self.handle, pchar ( 'query data error:' + err), 'error', MB_OK + MB_ICONERROR);      

end;

   And then there's the "Add", "Edit", "Delete" button, code and our usual operations, such as "Add" button code:

   cds.append;

   cds.fieldbyname('xxx').asinteger:=xxx;

   //....

   cds.post;

    Modify, delete also write. But now there is a small problem is that this generation question the primary key of the table, where we can not use auto-increment primary key, to generate primary keys themselves own, so you have to write an intermediate layer is generated in the middle layer the method of the primary key, when the "Add" button invokes the generate green primary key, then the above operation will not say much.

    CRUD finished, then the client's data is still in memory, to save the intermediate layer is necessary to use a remote server we have just the method, the following is the "Save" button under the code:

was err: string;

begin

    if cds.ChangeCount = 0 then exit; // data did not change would not have submitted

    if Dm.Conn.AppServer.ApplyUpdates ( 'xxx', cds.Delta, err) then // xxx is the name of the table

    begin

       MessageBox (self.handle, 'saved successfully!', 'Tips', MB_OK + MB_ICONINFORMATION);

        cds.MergeChangeLog; // merge all data changes

    end else MessageBox (self.handle, pchar ( 'save error:' + err), 'error', MB_OK + MB_ICONERROR);

end;

   This, the article also finished this way, those basic data to update a single table can also be written as an ancestor class, as long as the table name plus an updated virtual method to obtain, such as: function TableName:. String; virtual; then it As long as the offspring override this method, return to their table names, others do not have to write a code.

Guess you like

Origin www.cnblogs.com/jijm123/p/11468572.html