三层结构,用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都试过,都不行!谢谢高手指点!
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都试过,都不行!谢谢高手指点!
==
可以理解为:
CDSMaster.CommandText := 'Select * from Student';
如果用的sqlserver ,字段中有默认的时间他会把毫秒都带上,而你通过sql查询出来的数据
只有时分秒,所以在更新的时候如果updateMode设置为upwhereall,他会把每个字段都作为
where后面的条件进行
update table set .... where Field1=field1value and field2=field2value .....
在有这样的时间字段一过滤时,系统就找不到原来的那条记录了,因此就会抱错。
CDSMaster.CommandText := SQLStr1;
中的SQLStr1='Select a,b,c,d,e,f from Test'时将修改的数据更新回服务器时不会出错。可是一旦改为Select * from Test时,将修改后数据更新回服务器时就会出错了,不知道是什么原因,是不是字段太多了?但一般情况下数据库的极限字段是255个呀。
把它拷贝出来在查询分析器中执行以下,看看
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'
感觉也没有错呀!