有一个程序连接如下:Server部分: (SOAP方式)TSQLConnection连接数据库 (A_DB)
TSQLDataSet连接数据库中某个表 (A_Table)
TDataSetProvider 连接 TSQLDataSet (A_Provider)
TClientDataSet 连接 TDataSetProvider (A)Client部分:TClientDataSet 从服务端的 A 取数据 (A_Client)因为我们使用的表中数据比较大(最大可达100万),所以客户端一次设置读取数据100条(PacketRecords=100),但为了使客户端能够快速看到已浏览过的数据,客户端使用AppendData方式,如下示意:A_Client第一次   第二次   ....       第n次
100      100+100  ....       (n-1)*100+100     
         200      ....        n*100当我在第i次读完后,修改了某一条数据 x,然后应用到服务端,试验了两种方法:1.将 .Data中的数据传到服务端,赋给 A,再用 A.ApplyUpdate(-1),情况测试如下:
a.数据如果全部正确Apply到数据库中,A.Delta 将为空。
b.数据如果存在数据没有正确Apply到数据库中,A.Delta将留下没有Apply的数据日志,并且将响应A.OnReconcileError事件(我们可以将OnReconcileError中的信息和A.Delta传回客户端,进行容错处理,由用户决定如何处理该数据)。*特点:一次传到服务端的.Data 数据又可能很大,影响速度,但可以进行容错处理。2.将 .Delta 中的数据传到服务端,赋给 A, 再用 A.ApplyUpdate(-1)
a.数据如果全部正确Apply到数据库中,或数据如果存在数据没有正确Apply到数据库中,A.Delta都不变,并且不会响应OnReconcileError,我们无法知道数据是否Apply进去了,即我们无法进行容错处理。(事实上我们故意利用UpdateMode的upWhereAll 和 upWhereKeyOnly方式制造出能够正确Apply数据和无法Apply数据的现象)*特点:一次传到服务端的.Delta 数据可能很小,速度快,但不能进行容错处理。有没有人知道第3中方法,能够只将改变了数据的Data提取出来?(前三个解决问题的额外追加分值:第一个解决了问题的可以另开帖加100分,第二个解决问题的可以另开帖加50分,第三个解决问题的可以另开帖加25分)

解决方案 »

  1.   

    这个问题可能就是太依赖delphi的数据库功能了,显得编程的灵活性就小了。界面数据的修改,一般改动量较小,完全可以拼接sql语句直接提交到服务器进行数据库修改,不必每次把修改的数据集提到服务器更新的。
      

  2.   

    客户端将数据集打开编辑后,应用ApplyUpdate后,其实它就是只把新增的和更改后的数据提交到中间层server,并不象你说的那样,将所有的数据全都提交。我做过实验。我的项目也采用了他的这种特性,在中间层进行一些数据逻辑处理,然后提交给数据库。
    如果把全部数据提交的话,他的delta和log也就没用了。
      

  3.   

    我现在用的如下模式:Server: TDatabase+TQuery+TDataSetProvider
    Client: TSocketConnection+TClientDataSet编辑好数据后,直接 ApplyUpdates(-1),没有问题;如果Apply失败,会响应OnReconcileError而我上面是我正在试验的另外一个模式:
    Server: TDatabase+TQuery+TDataSetProvider+TClientDataSet (SOAP)
    Client: THTTPRIO+TClientDataSet
    它们之间的应用必须将客户端的TClientDataSet数据 .Data/.Dalta 通过接口传到服务端的 TClientDataSet,然后再Apply.对于 findcsdn 所说的 "拼接sql语句直接提交到" 也是一个办法,但同样存在容错无法处理问题。
      

  4.   

    对于你的第二种情况,datasetprovider.ApplyUpdates会返回更新错误的数据,这是一个OleVariant类型的变量,你在执行完datasetprovider.ApplyUpdates后把它的返回值(resultA)返回给客户端,然后在客户端执行clientData.Reconcile(resultA),就会触发clientdataset的OnReconcileError,然后该怎么办就怎么办。