更新 RDO 数据

并非所有的 rdoResultset 对象都可以被更新。有时候,不能使用游标来更新一个结果集,但可以使用动作查询来。为了用游标更新基本表,必须满足下面的条件:

通过存储过程进行更新

多数多用户系统中的应用程序不会试图直接对基本表进行更新。创建一个游标来更新选定的表的指定列,这看起来很简单,但系统管理员可能会禁止这种极其危险的操作。另外,数据库业务规则和关系的完整性经常依赖于逻辑操作中的相关表同步。数据库可能包含触发器或其它的机制,用来自动执行这些操作的一部分或者全部,因此应用程序就可以更简单,不必处理这些细节。

为了更新一个基本表,并使用 RDO 游标来执行一些辅助操作,可以在应用程序中开始一个事务,并管理更新操作的各个方面。这可以通过执行若干独立的更新操作来实现。但是,对于需要更新表的每一个应用程序,都需要复制这种相当复杂的方法。一旦业务规则或引用的完整性模式有所改变,应用程序就必须被重新编译并重新分发。

为了实现一种更好的解决方法,大多数情况下都使用存储过程来返回行结果集,并更新指定的数据行。这种方法增强了绝大多数的远程数据库和网络的安全机制,并且已经成功地实现于支持 1,000 或更多用户的系统中。该方法的另一个优点是高性能。因为应用程序通常是为了处理范围有限的结果集,并且不仅仅依赖于游标,所以,工作站、网络和远程服务器将更有效进行合作。

通过 WillUpdateRows 执行存储过程实现更新

RDO 2.0 允许在使用游标更新数据库时执行存储过程。这就意味着可以用自己的存储过程来添加、修改、删除数据。如果为 WillUpdateRows 事件编写了一个过程,那么可以提交一个存储过程来执行更新操作。或者只编写一些更新或其它的操作来代替基于游标的操作,或者作为附加的操作。

如果结果集不是批处理模式,那么在 ODBC 更新被送到服务器之前,每次调用 Update 方法都会触发 WillUpdateRows 事件。如果是批处理模式,则只有在 BatchUpdate 方法执行时才触发 WillUpdateRows 事件。

通过检查 WillUpdateRows 的 ReturnCode 参数,可以知道更新操作的成功或失败。下表总结了可以用作 ReturnCode 参数值的选项。

ReturnCode 表明
rdUpdateSuccessful 更新操作成功。RDO 不通知其它处理程序(如果该事件有多个的处理程序),并且将列标记为更新的。
rdUpdateWithCollisions 更新操作成功,但有些行产生了冲突(仅对批处理模式而言)。RDO 不通知其它处理程序(如果该事件有多个处理程序),也不标记更新过的列。
rdUpdateFailed 更新操作不成功。RDO 不通知其它处理程序(如果该事件有多个处理程序),并且触发一个可以捕获的运行时错误,不标记更新过的列。
rdUpdateNotHandled (缺省)应用程序并没有处理更新操作。RDO 继续通知其它处理程序(如果有的话)。如果没有其它过程执行更新,RDO 将更新数据并标记更新过的列。

使用游标更新数据源

如果数据库没有实现严密的引用完整性或复杂的业务规则,允许直接访问基本表,那么可以使用 rdoResultset 游标来更新数据行。注意,许多关于更新的问题都与并发管理有关,例如数据行和页的锁定,共享数据等。错误处理程序必须准备处理各种可能发生的情况,包括行和页锁定冲突、丢失连接、更新冲突以及其它许多可能性。

修改 rdoResultset 中数据行的值包括以下步骤:

  1. 使用“定位当前的行指针”一节中讨论的重定位当前行指针方法之一进行定位。

  2. 使用 Edit 方法激活要修改的行。所有数据都被复制到一个临时的行缓冲区中。

  3. 为需要修改的数据列提供新值。要使用临时行缓冲区,只需要使用 rdoResultset 对象的列,就象从数据列中检索数据时那样。

  4. 所有的数据列都修改为正确值之后,使用 Update 方法将行缓冲区保存到数据源。当前行被删除,缓冲区中的数据行取代了它。这时,LastModified 属性将返回被修改行的书签。

放弃编辑

在使用 Update 方法之前,并没有进行任何真正的修改,直到执行该方法时才将所进行的编辑提交到数据库。但是,如果决定放弃所作的编辑并返回当前行的未经编辑的版本,可以有以下这些选择:

编辑过后,当前行指针指向修改过的行,可能会定位在 rdoResultset 的末尾。要重新访问刚刚被修改过的数据行,可以使用 LastModified 属性提供的书签。

添加及删除 rdoResultset 数据行

除了修改指定数据行的列之外,还可以添加一行数据到 rdoResultset 中,即添加一行数据到基本表中。该操作假定应用程序具有读写访问权限,并允许添加数据行到基本表。因为情况常常不是这样的,所以必须详细了解 WillUpdate 事件,以及本章中关于使用存储过程的内容。

使用以下步骤添加指定的数据行到 rdoResultset:

  1. 使用 AddNew 方法创建一个临时的行缓冲区,用来保留待添加的新行。

  2. 为需要修改的每一列提供新值。要使用临时行缓冲区,只需要使用 rdoResultset 对象的列,就象从数据列中检索数据时那样。

  3. 使用 Update 方法将数据行保存到数据源。

添加完成后,如果游标支持对新的数据行的访问,那么当前行指针指向添加新行之前的当前行。在这种情况下,可以通过 LastModified 书签将指针移动到位于 rdoResultset 尾端的新添加的数据行。

添加了新的数据行之后,如果具有删除数据的权限(可能没有),可以从结果集中删除它。

使用以下步骤从 rdoResultset 中删除指定的数据行:

  1. 用某种 Move 方法、AbsolutePosition 或 PercentPosition 属性定位到该行。

  2. 使用 Delete 方法从游标(如果有)及数据源中删除该行。

删除完成后,当前行不再是有效的,因此必须重定位到 rdoResultset 的另一个有效行。

通过 RDO 动作查询进行修改

比 Edit、AddNew、Delete 和 Update 方法更有效的是使用 Execute 方法。执行包含一个或多个 UPDATE、INSERT、DELETE 语句的 SQL 查询,也可以对数据库进行修改。根据数据源的类型及支持复杂的多语句操作的能力,这些 SQL 可以执行所谓的“生成表”或 SELECT INTO 查询,查询用于创建临时或永久的新数据表,也可以执行其它的复杂操作。必须亲自管理错误和并发。也可以使用数据源支持的 SQL 语法提交事务语句,将若干个操作集中到一个或多个原子集合中。因为 Execute 方法也支持 rdAsyncEnable 选项,所以这些操作也可以异步执行。

注意   Execute 方法不是为返回数据行的查询而设计的。如果执行的存储过程既有“动作”操作,又返回数据行的操作,那么必须使用 OpenResultset 方法,分析产生的结果集。