使用 SCROLL 关键字创建滚动游标
使用 SCROLL 关键字创建滚动游标,它可以任何顺序取活动集合的行。
数据库服务器将游标的活动集合保留为一个临时表,直到关闭游标。您可以取得活动集合的第一 行、最后一行或任何一个中间行,以及在不必关闭再重新打开游标的情况下重复取得一些行。(请 参阅 FETCH。)
多用户系统中,在派生出活动集合的行的表中的行可能在打开游标之后有所更改,并且会在临时表 中生成一个副本。如果在一个事务内使用滚动游标,那么通过将隔离级别设置为“可重复读取”或通 过在事务期间以共享方式锁定整个表可以防止更改复制的行。(请参阅 SET ISOLATION 和 LOCK TABLE。)
以下示例为 SELECT 语句创建了一个滚动游标:
DECLARE sc_cur SCROLL CURSOR FOR SELECT * FROM orders;
您可以将 Select 和 Function 游标创建滚动游标,但不可为 Insert 游标创建滚动游标。不可将滚动 游标声明为 FOR UPDATE。
使用 WITH HOLD 关键字创建保持游标
使用 WITH HOLD 关键字创建 hold 游标。Hold 游标允许跨多个事务对行的集合进行不中断的访 问。
通常,所有的游标在事务结束时关闭。Hold 游标不会关闭;它在事务结束之后仍保持打开状态。 Hold 游标可以是一个顺序游标或(在 ESQL/C 中)滚动游标。
在 SPL 例程中 WITH HOLD 关键字只对 Select 游标有效。有关 DECLARE 语句在 SPL 例程中
的语法,请参阅 在 SPL 例程中声明动态游标。
在 ESQL/C 中,可以使用 WITH HOLD 关键字声明 Select 和函数游标(具有顺序和滚动属性)也 可以声明 Insert 游标。这些关键字在 DECLARE 语句中跟在 CURSOR 关键字之后。以下示例为 SELECT 创建了一个顺序 Hold 游标:
DECLARE hld_cur CURSOR WITH HOLD FOR SELECT customer_num, lname, city FROM customer;
您可以如下面的 GBase 8s ESQL/C 代码示例所示使用选择保持游标。此代码段使用一个 Hold 游 标作为主游标来扫描一个记录集合,使用一个顺序游标作为细节游标俩指向位于不同表中的记录。 主游标扫描的记录是更新细节游标指向的记录的基础。在第一个 WHILE 循环的每个迭代的结束处 的 COMMIT WORK 语句将 Hold 游标 c_master 保留为打开状态,但关闭顺序游标 c_detail 并 释放所有锁。这种技术最小化了数据库服务器必须分配给锁和未完成的事务的资源,并且它使其它 用户能够立即访问更新的行。
EXEC SQL BEGIN DECLARE SECTION; int p_custnum, int save_status; long p_orddate; EXEC SQL END DECLARE SECTION; EXEC SQL prepare st_1 from 'select order_date from orders where customer_num = ? for update'; EXEC SQL declare c_detail cursor for st_1; EXEC SQL declare c_master cursor with hold for select customer_num from customer where city = 'Pittsburgh'; EXEC SQL open c_master; if(SQLCODE==0) /* the open worked */ EXEC SQL fetch c_master into :p_custnum; /* discover first customer */ while(SQLCODE==0) /* while no errors and not end of pittsburgh customers */ { EXEC SQL begin work; /* start transaction for customer p_custnum */ EXEC SQL open c_detail using :p_custnum; if(SQLCODE==0) /* detail open succeeded */ EXEC SQL fetch c_detail into :p_orddate; /* get first order */ while(SQLCODE==0) /* while no errors and not end of orders */ { EXEC SQL update orders set order_date = '08/15/94' where current of c_detail; if(status==0) /* update was ok */ EXEC SQL fetch c_detail into :p_orddate; /* next order */ } if(SQLCODE==SQLNOTFOUND) /* correctly updated all found orders */ EXEC SQL commit work; /* make updates permanent, set status */ else /* some failure in an update */ { save_status = SQLCODE; /* save error for loop control */ EXEC SQL rollback work; SQLCODE = save_status; /* force loop to end */ } if(SQLCODE==0) /* all updates, and the commit, worked ok */ EXEC SQL fetch c_master into :p_custnum; /* next customer? */ } EXEC SQL close c_master;
使用 CLOSE 语句显式地关闭 Hold 游标,或使用 CLOSE DATABASE 或 DISCONNECT 语句隐 式地关闭 Hold 游标。CLOSE DATABASE 语句关闭所有游标。
使用保持 Insert 游标
如果您将保持游标与 INSERT 语句相关联,则可以使用事务将一长串的 PUT 语句打断为较小的 PUT 语句集合。除了等待 PUT 语句填充缓冲区并引发自动写入数据库,您可以执行 COMMIT WORK 语句刷新行缓冲区。使用 Hold 游标,COMMIT WORK 会提交插入的行,但将游标保留 为打开状态以供进一步插入。当插入大量的行时,这样方法是期望的,因为暂时的未提交的工作会 消耗数据库服务器的资源。




