三层结构,用ADOConnection+ADOQuery+DataSetProvider+SocketConnection+ClientDataSet,由于某种原因,客户端CDSMaster(ClientDataSet)修改后的数据不调用CDSMaster.ApplyUpdates()方法更新到服务器,所以自己就写方法更新数据到服务器。客户端从服务器获取数据方法:
  CDSMaster.Active := False;
  CDSMaster.CommandText := SQLStr1;         //用此SQL语句从服务器获取数据,服务器的ADOQuery的SQL为空
  CDSMaster.Execute;
  CDSMaster.Active := True;
客户端将修改后的数据更新到服务器的方法如下:
//SCMaster: TSocketConnection;
//CDSMaster: TClientDataSet;
begin
   CDSMaster.CheckBrowseMode;
    if CDSMaster.ChangeCount > 0 then
    begin
      MasterVar := CDSMaster.Delta;
      SCMaster.AppServer.ApplyUpdatesLyj(MasterVar, SQLStr1)   //调服务器的方法  SQLStr1是修改前用此SQL语句从服务器获取数据。
      if not VarIsNull(MasterVar) then
        CDSMasterPar.Reconcile(MasterVar)        
    end
    else
      MasterVar := NULL;
end;
服务器的方法:
//ADOQuery: TADOQuery
//DSPMaster:TDataSetProvider
procedure Tco_Server.ApplyUpdatesLyj(var vMaster: OleVariant; const SQLStr1: WideString);
var  
  ErrCount : integer;
begin
  ADOConnection1.Connected := True;
  ADOConnection1.BeginTrans;
  try
    ADQMaster.Close;                 
    ADQMaster.SQL.Clear;
    ADQMaster.SQL.Add(SQLStr1);    if not VarIsNull(vMaster) then   //主表
    begin
      vMaster := DSPMaster.ApplyUpdates(vMaster, 0, ErrCount);     //DSPMaster 是 DataSetProvider
      if ErrCount > 0 then
        SysUtils.Abort;              //这将产生回滚              
    end;
    ADOConnection1.CommitTrans;
  except
    ADOConnection1.RollbackTrans;
  end;
end;当数据库的字段少(5、6个)时,此方法能顺利将修改后的客户端数据更新回服务器,可是当字段大于50个时,这个方法更新时将出现:
Record not found or changed by another user
这个错误,不知道是什么原因?ResolveToDataSet为True和False都试过,都不行!谢谢高手指点!

解决方案 »

  1.   

    CDSMaster.CommandText := SQLStr1; 
    ==
    可以理解为:
    CDSMaster.CommandText := 'Select * from Student';
      

  2.   

    看一下你的字段中是不是有时间字段?
    如果用的sqlserver ,字段中有默认的时间他会把毫秒都带上,而你通过sql查询出来的数据
    只有时分秒,所以在更新的时候如果updateMode设置为upwhereall,他会把每个字段都作为
    where后面的条件进行
    update table set .... where  Field1=field1value and field2=field2value .....
    在有这样的时间字段一过滤时,系统就找不到原来的那条记录了,因此就会抱错。
      

  3.   

    谢谢MoveFirst兄的回复!我为了减少其他干扰,用SQL Server建了一个表(里面有50个全是char类型的字段),当
    CDSMaster.CommandText := SQLStr1; 
    中的SQLStr1='Select a,b,c,d,e,f from Test'时将修改的数据更新回服务器时不会出错。可是一旦改为Select * from Test时,将修改后数据更新回服务器时就会出错了,不知道是什么原因,是不是字段太多了?但一般情况下数据库的极限字段是255个呀。
      

  4.   

    那你就通过sql跟踪一下,看一下在提交时的 update 语句 是不是不完整?
    把它拷贝出来在查询分析器中执行以下,看看
      

  5.   

    我的表如下:
    a    b     c    d    e   ..............................
    66  55   66   66   NULL现在我在ClientDataSet中把数据改为:
    66  66  66   66
    提交给,事件探查器的更新语句如下:
    exec sp_executesql N'update Test  set
     b = @P1
    where
     a = @P2 and
     b = @P3 and
     c = @P4 and
     d = @P5 and
     e is null and
      ........
     48 is null and
     49 is null and
     50 is null
    ', N'@P1 char(10),@P2 char(10),@P3 char(10),@P4 char(10),@P5 char(10)', '66', '66', '55', '66', '66'
    感觉也没有错呀!
      

  6.   

    感谢MoveFirst由于使用ADO来控制事务,ResolveToDataSet应为False。现在我又把ResolveToDataSet改为False,就对了(可以保存了),真的很奇怪!