关于三层结构数据更新时,无法正确定位更新记录的问题!欢迎大家对DataSetProvider的UpdateMode属性的设置及使用进行讨论(300分)

  • 主题发起人 主题发起人 siyan
  • 开始时间 开始时间
S

siyan

Unregistered / Unconfirmed
GUEST, unregistred user!
我的一些疑惑:
1。UpdateMode=upWhereAll 时,通过所有的字段进行匹配,除了BLOB,浮点数字段无
法正确匹配外,还有什么类型的字段无法正确匹配
2。UpdateMode=upWhereKeyOnly时,如果无法找到匹配的键值会有什么原因呢
3。UpdateMode=upWhereKeyOnly时,根据更新的数据进行匹配,这样能保证匹配的纪录
唯一吗
请大家多多指教
 
2。UpdateMode=upWhereKeyOnly。。
原因多办是没有指定关键字段(关键字段一般是唯一的,如“编号”,ID)
3。UpdateMode=upWhereKeyOnly。。
一般不能保证唯一。
 
可是我可以肯定我的数据表中肯定存在主键
但是使用UpdateMode=upWhereKeyOnly 还是提示找不到这个键值
如果UpdateMode=upWhereKeyOnly一般不能保证唯一,那使用它还有什么意义吗
 
在另一个客户删除了而你却正更新这条记录的时候,记录就不能再更新了,就会出错
保证字段的唯一是很困难的,你只有结合更新记录时对错误的处理,来达到数据库数据的一致性
你出现到找不到键值的原因,应该是没有设置吧
如果你设置了就不知道和你用的数据库有没有关系
你用MSSQL嘛?我昨天晚上刚试的,是可以的呀
 
to funboy88
1、感谢你的参与
2、我绝对肯定我设置了主键
3、我可以保证在测试的时候只有我一个人在操作我操作的表
4、我用的是ORACLE数据库,主键是char型数据,有什么影响吗
 
把主键字段的属性设为 [pfinwhere,pfinkey,pfinupdate]就没事了
 
就你们说,这种结构,如果说根据主键来判断那假如有如下情况:
1。A获取到他要的5条记录(符合他条件的)
2。B同时获的5条记录,而且跟A相同(跟A的条件相同,此时A和B的记录都完全相同)
3。A改掉了一条(主键也改了)
4。B改了A的同一条和另外一条。
5。A先post。
6。B post 不了
这样该怎样处理呢?各位帮忙解决!
 
to YANCHAO28
是要在应用服务器端写代码设置吗,是不是因为我是使用客户端提交SQL语句
方式访问数据表,所以provider控件不知道我所查询表的主键?
to socool_100
我也不知道怎么处理
 
我也遇到同样的问题,无法解决。
to YANCHAO28
我按你说的方法作了,将主键字段的属性设为 [pfinwhere,pfinkey,pfinupdate],
还是不行,提示“Unable to find record. No key specified”
提交方式为ApplyUpdates(-1)
 
我认为最好用UpdateMode=upWhereChanged,
我现在就是这样做的,应用服务器各方面都很稳定。
 
主键跟外键是用于保持数据库表一致性的,upWhereKeyOnly需要的是一个唯一索引。
一般建表时指定了主键的话,会自动生成一个唯一索引,但如果是后来的生成的主键,索引
是要手工加的。
后台是oracle的话,还要注意的是它把''update到后台就变成null了。所以原来是''的,
再where xxx=''就没有记录,就是"changed by another的来源。
如果用的是BDE,而字段名是小写的话,update时会引起"Unable to find record. No key specified"
这同时跟ResoleToDataSet属性有关。
 
更疯狂的怀疑是你取数据后就与服务器端断开了连接,后来再想取更新数据,肯定会出错的
问:你在更新前有没有保持状态
多层开发问题很多的哦,呵呵
 
to szf
对你的答复的几个疑问
1、既然是对主键进行判断,主键值又怎么会是空呢
2、ORACLE好象不区分字段名的大小写吧
to taninsh
我的应用服务器肯定是无状态对象,不是很明白你所说的保持状态指的是什么
能不能解释一下
请大家继续指教
 
下面代码是appserver上一个Provider的BeforeUpdateRecord事件中的代码,
关于Provider和Field.ProviderFlag的详细资料你参考李维写的d5分布开发的系统篇。
procedure TiCRMSaleDataRDM.dspVAccountBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet;
DeltaDS: TCustomClientDataSet;
UpdateKind: TUpdateKind;
var Applied: Boolean);
var
i: Integer;
begin
//如果是调用DatasetProvider.ApplyUpdates就非常重要,因为在客户端静态设定
//字段的ProviderFlag中的fpInkey会在对ClientDataSet.Data赋值时丢失
for i := 0 to DeltaDS.RecordCount - 1do
begin
if not (pfInKey in DeltaDS.FieldByName('ID').ProviderFlags) then
DeltaDS.FieldByName('ID').ProviderFlags :=
DeltaDS.FieldByName('ID').ProviderFlags + [pfInkey];
end;
end;
 
to blue_morning
//如果是调用DatasetProvider.ApplyUpdates就非常重要,因为在客户端静态设定
//字段的ProviderFlag中的fpInkey会在对ClientDataSet.Data赋值时丢失
能解释一下其中原理吗,不是很明白
 
就是说你在客户端的clientDataSet中生成永久字段,然后使用Interceptor设定了字段
对象的ProvideFlage的值是为pfInkey,但程序运行后当clientDataSet.Data得到Provider
提供的数据集后这个设定并没有任何效果。所以要在Provider的更新之前设定哪一个字段
的ProviderFlag是pfInkey,这样Provider才能产生正确的描述SQL.(当然前提是provider.
ResoleToDataSet=false)
否则就会出现如下的错误:
"Unable to find record. No key specified"
 
然后使用Interceptor设定了字段
是对象查看器,应是inspector.
另外在我的代码中,ID字段是表的主键.
另外根据我自己的体会,对UpdateMode做一个简单的说明:
(设表为ID(Key), Name, Age)
upWhereAll :意味着provider生成SQL的Where条件会是:ID=从库中取走时的值, Name =从库中取走时的值, Age=从库中取走时的值
upWhereChange:如果只是Name和Age被修改过,SQL的条件是:Name =从库中取走时的值, Age=从库中取走时的值
upWhereOnlyKey:看你把那些字段设为Key,如果是多个则是And的关系.
 
to blue_morning
不好意思,我开始没有说清楚
我是使用客户端提交sql语句的方式与应用服务器交互的
也就是说,我没有生成任何永久对象,也没有设置字段对象的providerflag
这样的话,会是什么情况呢
 
如果没有设就是upWhereAll,你先照着上面的代码把程序实现一下。
 
后退
顶部