更新显示“检索和更新之间的行已更改”的 DataWindow 时出现错误。解决办法是什么?
7 回答
如果您在多个(非共享)DataWindow 中显示相同的行,然后尝试同时更新它们,则可能会发生这种情况。其他原因是不正确使用 SetItemStatus(); update() 语句中状态标志的错误使用;最后,这是要检测的原因,另一个用户更新了您之前的行。
这已经解决了吗?发生这种情况的原因有多种,一个是该行已被另一个用户更新。在数据对象的更新属性中,您可以选择更新方法,使用键值、键和修改的值,或者键和所有可更新的列。
如果您确定不存在并发问题,则可以将此设置更改为“仅使用键值”。它将使更新的 where 子句仅包含键值,并且不会评估其他列的更改。
如果发生验证错误,可能会发生这种情况,您需要记住将项目状态设置为未修改。要将所有行设置为未修改,如果我的记忆正确,您将执行 dw_1.setitemstatus(1,0,Primary!,NotModified!) 将第一行的所有列设置为 NotMofidied!。您还可以执行 ResetUpdate() 或重新检索数据。
希望这可以帮助。富有的
这通常意味着您在 update where 子句中包含的某些列正在其他地方更新,例如通过触发器。另一个原因包括在与 oracle 交谈时没有为字符串列设置空字符串。oracle 将发送给它的任何空字符串转换为空值,因此后续更新不会找到相同的行,除非您告诉 pb 也将其视为空值。查看您告诉 pb 包含在 where 子句中的列(在更新规范中),并确保它们确实是您需要的列。
我意识到这是一个老问题,但我想我会添加我的解决方案以防它帮助任何人。就我而言,数据窗口正在发出一条UPDATE
语句,当该语句在 SQL 管理工作室中运行时,返回的列与预期的匹配。但是,查询显示了两次(1 行受影响)。触发器正在更新与正在更新的表无关的行。添加SET NOCOUNT ON
到该触发器导致 1 个实例(受影响的 1 行)和检索和更新之间的行更改已解决。
当您有两个更新相同数据库行或行的数据窗口行时,也会发生这种情况。
(不太好)示例:
该表没有主键,但数据窗口使用 DateOfBirth。
姓名:丹尼斯·米勒 出生日期:19531103 职业:喜剧演员
姓名:凯特·卡普肖 出生日期:19531103 职业:女演员
请注意,Dennis 和 Kate 具有相同的 DateOfBirth。
让我们假设进行了这些更改
姓名:丹尼斯·米勒先生
姓名:凯特·卡普肖女士
调用 dw_1.update() 时,会出现以下消息:
“检索和更新之间的行已更改”
因为每一行都更新了两次,首先是“先生”。丹尼斯米勒”,然后是“女士”。凯特卡普肖
另一种可能是数据窗口列定义与数据库列定义不匹配。
例子:
columnA 在数据库中定义为 char(10)
数据窗口是用 columnA 作为 char(10) 构建的
columnA 在数据库中更改为 char(20)
数据以超过 10 个字符从外部添加到列 A。
datawindow 检索截断为 10 个字符(有或无错误,具体取决于应用程序设置。)
删除/更新行可能会产生“检索和更新之间的行已更改”
此行为由数据窗口的“更新属性”监控,更具体地说,由“更新/删除的 Where 子句”部分监控。这控制了 Powerbuilder 在update.deleting 时将使用的“where”子句,您可以使用 Datawindow 的 SQLPreview 事件进行检查:
- 键列: where 子句中只使用键列。如果您使用它,您将面临在检索和更新之间某些列已在其他地方(不一定由 PowerBuilder)修改的风险。只有最新的更新将保留在数据库中。当然,如果键列本身已被修改,您将收到消息“行已更改”。
- 关键列和可更新列:在关键列的顶部,您可以在“可更新列”框中添加所有可更新列,如下面的定义。每当修改了列(同样不一定使用 Powerbuilder),将不会检索该行,并且您将收到消息“行已更改”。在许多情况下,这太过分了。
- 键和修改的列:只有为特定行修改的列才会添加到它们的键中。
现在取决于您的应用程序的特定上下文,您可以选择其中之一。