三层结构,新增一个记录后保存,正常,再修改时发现数据无论如何都更新不进去了,出错信息是‘Record not found or changed by another user’,在cds.ApplyUpdates后面加上cds.Refresh,可以保存,但换了一个复杂一点的表(有日期或浮点型字段的大概),问题又出现了,不知道谁有没有碰到这种情况,有什么办法解决?
BTW:试过最简单的三层结构,只写了两句更新数据的代码,也会这样
BTW:试过最简单的三层结构,只写了两句更新数据的代码,也会这样
jing lai zai shuo
在默认得情况下,Delphi会自动生成提交数据自动生成SQL,由于insert没有where语句,所以肯定成功。而where中如果有这些类型,SQL就无法准确定位记录,当记录不能定位时,只好报错“Record not found or changed by another user”(因为Delphi以为记录被别的用户修改了)。
这样就可以了。Good Luck。
多谢
to chechy
多谢
我回去试一下 可以的话就发分
通常情况下即使有浮点型字段或者日期字段也是可以更新的,偏偏我那天选择测试的一个数据表中有一个标识列,所以我还以为是比较普遍的问题
现在原因是清楚了,很明显,提交含有标识列(自增)或默认值的数据表的记录时,SQL SERVER会自动给这些字段赋值,更改记录,所以系统就定位不到这些记录了,出现‘record has changed’异常比较彻底的解决方法是删除数据库中的所有标识列同时去除所有的默认值按照 chechy的方法可以解决有主键的单表的问题,我是这样处理的,因为是在TClientDataSet的CommandText里边写SQL语句连接数据表的,所以直接在TClientDataSet的字段列表中设置ProvierFlags属性不行,需要在应用层的相应的TDataSetProvider的
BeforeUpdateRecords事件中写代码var
I, J: Integer;
begin
with DeltaDS do
begin
for I := 0 to RecordCount-1 do
for J := 0 to FieldCount-1 do
with Fields[J] do
if (pfInWhere in ProvierFlags) and not (FiledName = 'iNo') then ProvierFlags := ProvierFlags - [pfInWhere];
end;
end;但是现在问题还只解决了一部分
如果是没有主键并且批量更新或者是主明细表结构(没有给明细表设主键),这时候新的问题又出来了,事实上也是小小提到的这个限制:必段将唯一识别字段例入永久字段例里
设置应用层相应的TDataSetProvider的UpdateMode为upWhereKeyOnly,然后在其BeforeUpdateRecord事件中
var
I, J: Integer;
begin
with DeltaDS do
begin
for I := 0 to RecordCount-1 do
begin
for J := 0 to FieldCount-1 do
begin
with Fields[J] do
if not (pfInKey in ProviderFlags) and not (FieldName='id') then ProviderFlags := ProviderFlags + [pfInKey];
end;
end;
end;
end;
//id为标识列名称
//如果保留数据库中的默认值,在TClientDataSet的ApplyUpdates语句后加上Refresh
但是有时候Refresh会出问题,???