ODBC 动态游标

动态游标就是:动态。 它可以检测在打开游标后对结果集中的成员资格、顺序和值所做的任何更改。 例如,假设动态游标提取两行,然后另一个应用程序将更新这两行之一并删除另一行。 然后,如果动态游标尝试提取这些行,它将找不到已删除的行,但会返回已更新行的新值。

动态游标可检测其自己的更新、删除和插入,以及他人所做的所有更新、删除和插入。 (这受事务的隔离级别的约束,由 SQL_ATTR_TXN_ISOLATION 连接属性设置。)SQL_ATTR_ROW_STATUS_PTR 语句属性指定的行状态数组反映了这些更改,可以包含 SQL_ROW_SUCCESS、SQL_ROW_SUCCESS_WITH_INFO、SQL_ROW_ERROR, SQL_ROW_UPDATED 和 SQL_ROW_ADDED。 它无法返回 SQL_ROW_DELETED,因为动态游标不会返回行集外已删除的行,因此不再识别结果集中或其相应元素在行状态数组中是否存在已删除的行。 仅当调用 SQLSetPos 更新行时,才会返回 SQL_ROW_ADDED,而不是另一个游标更新该行时返回。

在数据库中实现动态游标的一种方法是创建定义结果集成员资格和排序的选择性索引。 由于当他人进行更改时会更新索引,因此基于此类索引的游标对所有更改都敏感。 通过沿着索引进行处理,可以在此索引定义的结果集中进行其他选择。

可以通过要求按唯一键对结果集进行排序来模拟动态游标。 在此限制下,每次游标提取行时,都会通过执行 SELECT 语句进行提取。 例如,假设结果集由以下语句定义:

SELECT * FROM Customers ORDER BY Name, CustID  

要提取此结果集中的下一个行集,模拟游标会将以下 SELECT 语句中的参数设置为当前行集最后一行中的值,然后再执行它:

SELECT * FROM Customers WHERE (Name > ?) AND (CustID > ?)  
   ORDER BY Name, CustID  

此语句创建第二个结果集,其中的第一个行集是原始结果集中的下一个行集 - 在本例中,它是 Customers 表中的行集。 游标会将此行集返回到应用程序。

请注意,以这种方式实现的动态游标实际上会创建许多结果集,从而允许它检测原始结果集的更改。 应用程序从不了解这些辅助结果集是否存在;看起来,游标似乎能够检测到对原始结果集的更改。