三层问题..求教(100分)

  • 主题发起人 主题发起人 冒险家
  • 开始时间 开始时间

冒险家

Unregistered / Unconfirmed
GUEST, unregistred user!
如何确保三层数据提交的稳定性????
 
最近我做了三层程序..
客户端....我是用 ApplyUpdtate(0) 提交数据 发现数据没被即时更新...不稳定..
不知什么原因...还请大家指点...
 
我也有同样的问题。不知道怎么解决。
 
直接用标准plsql就行呀!不用ApplyUpdtate(0) 这个,用insert into values
和update 若是 oracle就加上 begin
Sql;
end;
或者 sql;commit;
 
我以前也是碰到过这样的问题,
不过已解决
方法不知道是不是笨了点。但行得通。
你可以是服务器端建一个更新函数,(比如ADD_table_record )
然后用客户端来调有这个函数,
最后在服务器中写一个更新表的函数,
当调用了更新函数后,再调用更新表的函数,最后重新连接一下就行了
 
我以前也是碰到过这样的问题,
不过已解决
方法不知道是不是笨了点。但行得通。
你可以是服务器端建一个更新函数,(比如ADD_table_record )
然后用客户端来调有这个函数,
最后在服务器中写一个更新表的函数,
当调用了更新函数后,再调用更新表的函数,最后重新连接一下就行了
 
更新不了数据的原因多种多样,估计lz要的是一个了解为什么更新不了的途径。
1 如果你是用sql server的,你可以截获更新的sql看看,为什么更新不了一目了然了。
2 服务器端在发生更新不了的情况的时候,都会返回错误给你,你可以在服务器处于Debug状态的时候更新一下数据,看看是否产生了异常。
3 服务器更新不了数据时都会产生异常,把你的异常送会客户端显示吧。clientdatset有对应的方法的。半年没搞它了,都忘记了是什么方法了,你查查帮助。
 
估计更新不了的情况有以下几种
1 找不到匹配的数据,数据被修改了。这种情况一般发生在全匹配的更新模式中,用主建匹配的模式吧。
2 生成了错误的sql代码。这种情况一般都发生在用一个dataprovider对应多个clientdataset的条件下,服务器端用错了表,生成错误的更新sql。更新数据前,把你取数据的sql语句赋值给对应的dataset。
3 数据满足不了数据库的约束条件。截获生成的sql看看那些满足不了,在保存前验证一下。
 
感谢各位回帖..
讨论还在继续...做三层的朋友 遇到的困难 都可以拿来讨论:
服务端用
ADOConnection1
ADOTable1
DataSetProvider1
SQL2000
客户端
ClientDataSet1
DCOMConnection1
DataSource1
DBGrid1
加数据
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.Append;
ClientDataSet1.FieldValues['AA']:=143;
ClientDataSet1.FieldValues['BB']:='dfasdfas';
ClientDataSet1.FieldValues['CC']:=now;
ClientDataSet1.Post;
end;

更新
procedure TForm1.Button2Click(Sender: TObject);
begin
ClientDataSet1.ApplyUpdates(0);

ClientDataSet1.Refresh;
end;

客户端保存记录成功后客户端不刷新
DBGrid1没有刚才保存的数据
重新运行程序就有了
 
是啊,
你还没有弄好
我说了,,先把服务器端更新,(ADOTable1:=false;ADOTable1:=true<这样就是更新了服务器端更新了>)
然后客户端在重新连接一下(ClientDataSet1:=false;ClientDataSet1:=true<这是客户端更新>

按照这样的方法就OK了
 
在服务器端那里放置 ADOTable1:=false;ADOTable1:=true 这个好呢:
在客户端那里放置 ADOTable1:=false;ADOTable1:=true 这个好呢:
 
我最近也在做三层,客户端TClientDataSet+soket server+sql server;
最近发现一个问题,我在客户端给服务器端的存储过程传参数是,存储过程的参数如果是
ftstring类型,当你传的参数是汉字时,则无法正确传入参数,最多只能传一个汉字,不知道这是为什么,如果是英文或数字就没有问题,我将ftstring类型改成ftwidestring也不行;
另外还有一问:存储过程的image类型的输入参数,应该怎么使用啊,也就是我在存储过程里有个image类型的输入参数,那我该怎样赋值,才能将图片文件传给存储过程并保存到数据库呢?
 
对楼上 “冒险家”的回答,我也曾用过,但是总觉得这种效率太低,而且对服务器端不好维护,如果更新数据量太大的话,会引起死机。
 
问题: 关于三层数据提交的问题(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,
 
更新不到有可能是因为不同的TClientDataSet用了同一个TDataSetProvider,我在试验时发现一个TClientDataSet要对应一个Provider,不可两个对应一个,不然会出现问题,而且每个Provider要对应一个独立的数据源
 
后退
顶部