三层结构中,中间层的数据模块中有TMSSQLConnection、TSQLQuery、TDataSetProvider三个控件。
TSQLQuery为关闭状态,且没有写入SQL语句。TDataSetProvider1与TSQLQuery相连接。问题是这样的:
客户端的ClientDataSet通过DCOMConnection获取中间层的TDataSetProvider接口,程序执行后,为ClientDataSet加入SELECT * FROM books的语句后,获得数据集。在客户端的DBGrid中修改了books的记录后,如果直接调用ClientDataSet的ApplyUpdatas(0)则更新成功。但如果我在中间层定义一个方法UpdateBooks,客户端通过调用这个方法实现更新时却不成功。服务器:
procedure TNT_Main.UpdateBooks(vDatas: OleVariant; var iErrorCount: Integer);
begin
    DataSetProvider1.ApplyUpdates(vDatas, 0, iErrorCount);
end;客户端
procedure TfrmSiteinfo.BitBtn2Click(Sender: TObject);
var
    iErrorCount: Integer;
    vDatas: OleVariant;
begin
    vDatas := frmDM.ClientDataSet1.Delta;
    frmDM.ScktConn.AppServer.UpdateBooks(vDatas, iErrorCount);    if iErrorCount = 0 then
        showmessage('更新成功')
    else
        showmessage('发生错误');
end;

解决方案 »

  1.   

    试试这种做法,
    应用服务器端;
    unit Unit2;{$WARN SYMBOL_PLATFORM OFF}interfaceuses
      Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
      DBClient, Project2_TLB, StdVcl, Provider, DB, ADODB;type
      Ttestapp = class(TRemoteDataModule, Itestapp)
        ADOConnection1: TADOConnection;
        ADODataSet1: TADODataSet;
        DataSetProvider1: TDataSetProvider;
        procedure RemoteDataModuleCreate(Sender: TObject);
      private
        { Private declarations }
      protected
        class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
        procedure mm; safecall;
      public
        { Public declarations }
      end;
        function GetRegInfo(Flag:integer):ShortString;external 'OPUHIS.DLL';
    implementation{$R *.DFM}class procedure Ttestapp.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
    begin
      if Register then
      begin
        inherited UpdateRegistry(Register, ClassID, ProgID);
        EnableSocketTransport(ClassID);
        EnableWebTransport(ClassID);
      end else
      begin
        DisableSocketTransport(ClassID);
        DisableWebTransport(ClassID);
        inherited UpdateRegistry(Register, ClassID, ProgID);
      end;
    end;procedure Ttestapp.RemoteDataModuleCreate(Sender: TObject);
    begin
    ADOConnection1.ConnectionString :=' Provider=SQLOLEDB.1;'+
        'Persist Security Info=False;User ID='+GetRegInfo(3)+';Password='+GetRegInfo(4)+';'+
        'Initial Catalog='+GetRegInfo(2)+';Data Source='+GetRegInfo(1);
    end;procedure Ttestapp.mm;
    begin
     ADODataSet1.Close;
     ADODataSet1.CommandText:='select * from MaintManView';
     ADODataSet1.Open;
    end;initialization
      TComponentFactory.Create(ComServer, Ttestapp,
        Class_testapp, ciMultiInstance, tmApartment);
    end.客户端:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, DBGrids, StdCtrls, Buttons;type
      TForm1 = class(TForm)
        DBGrid1: TDBGrid;
        BitBtn1: TBitBtn;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementationuses Unit2;{$R *.dfm}procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
    DataModule2.APPS.mm;
    DataModule2.ClientDataSet1.Open;
    end;end.
      

  2.   

    通过调用中层自定义的方法给客户端传回查出的数据没问题。直接调用客户端的ClientDataSet.ApplyUpdates(0)更新也行。就是通过调用中间层自定义的方法,给中间层传送ClientDataSet.Delta,
    中间层用frmDM.ScktConn.AppServer.UpdateBooks(vDatas, iErrorCount);
    来更新的话就会不成功。
      

  3.   

    贴错了,中间层执行的是DataSetProvider1.ApplyUpdates(vDatas, 0, iErrorCount);
      

  4.   

    如果DataSetProvider和ClientDataSet放在一层里,就是做成一个程序,那么
    DataSetProvider1.ApplyUpdates(vDatas, 0, iErrorCount);就可以更新成功.
    只要是分开层来做就不行.
      

  5.   

    是不是TSQLQuery的SQL没设置
    我现在是这样用的DataSetProvider1.ApplyUpdates(vDatas, 0, iErrorCount)
    没有什么问题不过我现在不知如何回写ClientDataSet1.Delta;