问题: 关于三层数据提交的问题(300分) ( 积分: 100 )
分类: MIDAS / DCOM
来自: wxkabc, 时间: 2002-11-02 20:24:00, ID: 1409665
我所作的三层服务器是采用Socket连接的(后台数据库是Oracl),
其功能已近完善。只是在最近的测试中发现存在提交数据失败的
现象,根据本人的跟踪调试发现数据提交不上去的存在一定的规
律性。
其规律如下:
当在客户端修改字符串型字段的数据时,把其值清空(假设原来
有值)保存正常,之后再修改该字段值提交则发生如下错误:
Record not found or changed by another user
如果不将其值清空而是直接输入另一字符串则不会出现上述问题。
请各位高手赐教:发生上述问题的原因是什么?如何解决?
来自: szf, 时间: 2002-11-02 22:12:00, ID: 1409833
进行数据更新的数据集组件(或ClientDataSet连接的DataSetProvider组件,要看你的程序而定)
的UpdateMode改为upWhereKeyOnly
这是数据库中主键设置不正确所至,或者是其它原因,不过要看整个数据库的结构才知道。
来自: wxkabc, 时间: 2002-11-02 22:51:00, ID: 1409870
首先谢谢szf的回答。
对于将UpdateMode改为upWhereKeyOnly
我也试过,但总是提交失败,是否还得设置其它属性,还望赐教。
其它两种UpdateMode我都试过,对于我的问题它们没有什么区别。
对于表的结构我想影响不大,因为我们做的系统有几百个表,凡我
测试过的表都存在此问题。
来自: juanZ, 时间: 2002-11-02 23:08:00, ID: 1409886
我也碰到类似的问题,也出现Record not found or changed by another user
后来发现是表的字段名问题,我用的是ACCESS2000
来自: billrobin, 时间: 2002-11-03 0:23:00, ID: 1409948
Record not found or changed by another user
我告诉您解决方法,您在保存数据后,再取一次数据,再修改,如果保存后,一定要再取
一次数据。否则要出错,保存----取数据---修改----保存---取数据。。。。。
OK
来自: zhongtu, 时间: 2002-11-03 8:33:00, ID: 1410029
注意:我也遇到过该问题,解决方法如下:
1.将UpdateMode改为upWhereKeyOnly
2.用midas.dll 7.0(delphi7自带,用Regsvr32 注册)
OK!(我刚解决3天!^_^。主要原因还是midas.dll版本太低,功能受限制!)
来自: wxkabc, 时间: 2002-11-03 9:31:00, ID: 1410064
谢谢各位的建议!
对于 juanZ 的所说的我想不大可能,因为我用的几百个表不可能都是字段名的问题。
对于 billrobin 的提议,我也认为不可行。我们做的MIS的数据量比较大
如果这样做的话会大影响系统的效率。
对于 zhongtu,的第一种方法上面我已经提过。第二种方法我的同事也试过,好象也
不行,是否有其它应该注意的地方请指点。
谢谢大家!
来自:do
nkey, 时间: 2002-11-03 9:40:00, ID: 1410072
这个bug从以前就有,如果你将字段值设置为允许为空就可以,但是这无助于问题的解决.
根本的办法就是在提交前进行检查,如果发现是空的就滤掉它.我就是这样解决的,但是
你使用的是数据库控件,又是三层的,非常麻烦.
来自: szf, 时间: 2002-11-03 13:38:00, ID: 1410377
billrobin的方法是对的。
通过SQLMonitor观察,发现如果如楼主的做法,则第二次update操作时,BDE产生的
sql语句是 where DataField='',而再重新打开ClientDataSet后进行update时,BDE产生的
sql语名是 where DataField is null
Oracle把''保存到数据库时自动变成null,所以上面的where DataField=''不能更新任何数据,
就报"Record not found or changed by another user"了。
另一个解决办法是
把DataSetProvider的ResolveToDataSet设置为True,对应的TQuery组件的RequestLive为True
就没有这个问题了。
但通过SQL-Monitor观察,发现在客户端程序ApplyUpdates时,应用服务器的做法也是重新
select一次数据,然后再update数据的。
至于哪种方法速度快,可以测试一下再决定了。
不过第二种方法对客户端程序来说是透明的,编程时不用考虑太多后台的事情。而且重新
select的数据只在oracle和appserver之间流动,估计会比第一种方法快。
来自: wxkabc, 时间: 2002-11-03 14:12:00, ID: 1410415
我知道billrobin的方法是对的,但在数据量大的情况会影响一定的速度。
我分析出现"Record not found or changed by another user" 问题的原
因与你所说的一样。
对于您所说的第二种方法,我们用的是ADO,所以不存在RequestLive的设置
问题。而我们的应用服务器也是先Select数据然后再ApplyUpdates提交。
来自: szf, 时间: 2002-11-03 14:39:00, ID: 1410447
使用ADO就更简单了,只要把DataSetProvider的ResolveToDataSet设置为True就可以,
连字段名的大小写都不用考虑。
反而用默认的False好象更新不了数据,不知是不是用了缓冲池有关。你那里是怎么样的?
来自: lop, 时间: 2002-11-03 16:00:00, ID: 1410578
听!
来自: wxkabc, 时间: 2002-11-03 17:01:00, ID: 1410669
我这里是使用了缓冲池,但我认为与它无关。我认为你前面说的比较正确
是Oracle把''保存到数据库时自动变成null,而客户端的值为'',所以再
次提交时就会发生“Record not found or changed by another user”。
但我不知除重新打开数据集外是否有其它方法能解决此问题?
谢谢你的支持‘szf’。
来自: szf, 时间: 2002-11-03 17:19:00, ID: 1410704
在我这里没有问题,也是用了缓冲池(Demo/midas/pooler范例改写的),
只修改了DataSetProvider的ResolveToDataSet的设置为True就一切OK了。
按你的"规律"来操作,一点儿问题也没有。
我不知道你有没有按我说的方法来做。
来自: wxkabc, 时间: 2002-11-03 17:34:00, ID: 1410728
我认为是客户端的数据不能刷新的问题,因为我的服务器是
不保留状态的,而提交则是自己写的方法把数据包发到服务
器上进行提交,这样在保存后再对客户端进行刷新。可能是
我处理有问题,我试了直接用ApplyUpdates提交是没什么问
题。
来自: billrobin, 时间: 2002-11-03 23:38:00, ID: 1411131
反过来说,您用的ApplyUpdates并不是完全意义上的三层。我曾经见过一个十分稳定的三层
。基本上不用ApplyUpdates。全由SQL在中间层完成。我遇到过您的问题。实际上取数据并
不是要花多少时间。我试过。或者,您改一下BDE的参数。INIT。
来自: zhongtu, 时间: 2002-11-04 8:58:00, ID: 1411286
前提:
1.DataSetProvider的ResolveToDataSe
其连接的Query的Requestlive为True
2.更新表不要有SN(自增字段)
3.日期字段不要用默认值
方法:(注意,1--2是步骤,不是两种方法)
1.将UpdateMode改为upWhereKeyOnly
2.用midas.dll 7.0(delphi7自带,用Regsvr32 注册)
我已成功,此问题困扰我一个多星期!
但对自增字段来说,我只能用SQL语句
来自: zag2000, 时间: 2002-11-04 14:04:00, ID: 1411884
我也遇到过同样的问题,我也采用了midas.dll 7.0,可是还是不行,请楼上给出详细的
实施办法好嘛?
我现在的解决办法是全部采用SQL语句来提交记录,在客户端自动产生INSERT/UPDATE的SQL
语句,传到应用服务器去执行SQL。但是这种方法存在一些问题,对于LONG RAW、BLOB等大
字段不知道如何使用SQL语句提交,如果那位有方法,那就可以解决了。
来自: wxkabc, 时间: 2002-11-04 14:53:00, ID: 1412021
[
][?]
重新声明:
经过我今天的测试发现,不管如何提交仍存在
"Record not found or changed by another user"的问题。
测试方法还是上面提过的。
所以请各位多提些建议。
我现在用的也是 Midas.dll 7.0,问题并没有解决。[
][
!]
来自: zag2000, 时间: 2002-11-07 18:24:00, ID: 1419789
我找到一个解决方法,原因就是varchar2类型的数据当为''(空)时,当提交到应用服务器
上的时候,应用服务器去回记录的时候变成Null,所造成的。
解决方法:
修改VCL中的DBCtrls.pas单元中的TDBEdit,TDBMomo等可以输入空字符数据的类,在它的
UpdateData方法修改如下:
procedure TDBEdit.UpdateData(Sender: TObject);
begin
ValidateEdit;
if Trim(Text) = '' then
FDataLink.Field.AsVariant := Null
else
FDataLink.Field.Text := Text;
end;
procedure TDBMemo.UpdateData(Sender: TObject);
begin
if Trim(Text) = '' then
FDataLink.Field.AsVariant := Null
else
FDataLink.Field.AsString := Text;
end;
来自: wxkabc, 时间: 2002-11-07 18:26:00, ID: 1419794
哈哈,原来是Delphi组件的数据处理有问题,问题已经解决
谢谢大家的参与。
来自: szf, 时间: 2002-11-08 10:01:00, ID: 1420793
根本就不是组件问题,只是oracle把''当成null来处理引起的。
这样改源码后,开发sybase,mssql,access等都会出问题的。
如果真要改,在DataSource的OnUpdateData事件中处理就可以了,不要轻易修改delphi的源码.
来自: HON, 时间: 2003-08-10 10:13:00, ID: 2097983
ZHONGTU对的,
"前提:
1.DataSetProvider的ResolveToDataSe
其连接的Query的Requestlive为True
2.更新表不要有SN(自增字段)
3.日期字段不要用默认值
方法:(注意,1--2是步骤,不是两种方法)
1.将UpdateMode改为upWhereKeyOnly
2.用midas.dll 7.0(delphi7自带,用Regsvr32 注册)
我已成功,此问题困扰我一个多星期!
但对自增字段来说,我只能用SQL语句 "
但是,之前DataSetProvider的ResolveToDataSeT=FALSE
主表出现"Record not found or changed by another user"的问题。
单独改明细表可以
按(1)改,明细表出现 DATASET CLOSED错误.
来自: desert, 时间: 2004-12-21 16:16:17, ID: 2939397
我用的是DBexpress+TclientDataset+TdatasetProvider查询出数据集修改后提交就报这个错了!
以上的方法我都试过了,还是不行啊!
来自: ldb518, 时间: 2004-12-21 22:27:26, ID: 2939734
我也遇到同樣的問題,但不是字符串﹐而是Float類型的,BCDField只允許3位小數﹐Money型也只有4位小數﹐超過4位小數也就只能用TFloatField,這種類型一使用﹐每二次ApplyUpdates就報錯﹐日期時間型的也有此問題﹐將UpdateMode改为upWhereKeyOnly﹐將ResolveToDataSeT設為True都不管用,看來只有試其他辦法了﹗我想升級到Delphi2005不知有沒有用﹖
得分大富翁: billrobin-5,szf-10,zag2000-85,