CURSOR
功能描述
CURSOR命令用于创建一个游标,从一个查询里面检索出指定的几行数据。
为了处理SQL语句,存储过程线程分配一段内存区域来保存上下文联系。游标是指向上下文区域的句柄或指针。借助游标,存储过程可以控制上下文区域的变化。
注意事项
- 游标命令只能在事务块里使用。
- 通常游标和SELECT一样返回文本格式。因为数据在系统内部是用二进制格式存储的,系统必须对数据做一定转换以生成文本格式。一旦数据是以文本形式返回,客户端应用需要把它们转换成二进制进行操作。使用FETCH语句,游标可以返回文本或二进制格式。
- 应该小心使用二进制游标。文本格式一般都比对应的二进制格式占用的存储空间大。二进制游标返回内部二进制形态的数据,可能更易于操作。如果想以文本方式显示数据,则以文本方式检索会为用户节约很多客户端的工作。比如,如果查询从某个整数列返回1,在缺省的游标里将获得一个字符串1,但在二进制游标里将得到一个4字节的包含该数值内部形式的数值(大端顺序)。
- 静态游标支持定义参数,参数支持默认值。但是参数默认值不能应用PACKAGE外的变量,如果需要使用,可以在包内定义一个变量,再将包外变量赋值给该变量,使用该变量作为默认值。
- 游标的定义会产生查询对象,PACKAGE或存储过程暂不支持建立对查询对象的依赖关系。
语法格式
CURSOR cursor_name [ BINARY ] [ NO SCROLL ] [ { WITH | WITHOUT } HOLD ] FOR query;
参数说明
- cursor_name
将要创建的游标名。
取值范围:遵循数据库对象命名规范。
- BINARY
指明游标以二进制而不是文本格式返回数据。
- NO SCROLL
声明游标检索数据行的方式。
- NO SCROLL:声明该游标不能用于以倒序的方式检索数据行。
- 未声明:根据执行计划的不同,自动判断该游标是否可以用于以倒序的方式检索数据行。
在cmdsql中,只支持添加NO SCROLL关键字或者不添加滚动选项,不支持添加SCROLL关键字。
在存储过程中,支持添加NO SCROLL、SCROLL关键字,或者不添加滚动选项。
显式游标中,只有声明为NO SCROLL的游标可以并发执行,建议将不需要用到倒序检索数据行方式的游标设置为NO SCROLL。
- WITH HOLD | WITHOUT HOLD
声明当创建游标的事务结束后,游标是否能继续使用。
- WITH HOLD:声明该游标在创建它的事务结束后仍可继续使用。
- WITHOUT HOLD:声明该游标在创建它的事务之外不能再继续使用,此游标将在事务结束时被自动关闭。
- 如果不指定WITH HOLD或WITHOUT HOLD,默认行为是WITHOUT HOLD。
- query
使用SELECT或VALUES子句指定游标返回的行。
取值范围:SELECT或VALUES子句。
示例
示例1:
--建表并插入数据。 gaussdb=# CREATE TABLE tbl_test(c1 int); gaussdb=# INSERT INTO tbl_test VALUES (generate_series(1,20)); --建立一个名为cursor1的游标。 gaussdb=# BEGIN; gaussdb=# CURSOR cursor1 FOR SELECT * FROM tbl_test ORDER BY 1; --使用FETCH命令检索3行数据。 gaussdb=# FETCH FORWARD 3 FROM cursor1; c1 ---- 1 2 3 (3 rows) --使用MOVE命令使游标向后移动2行,不返回结果。 gaussdb=# MOVE FORWARD 2 FROM cursor1; MOVE 2 --使用FETCH命令检索两行数据。 gaussdb=# FETCH FORWARD 2 FROM cursor1; c1 ---- 6 7 (2 rows) --关闭游标并结束事务。 gaussdb=# CLOSE cursor1; gaussdb=# END;
--建立一个名为cursor2的WITH HOLD游标。 gaussdb=# BEGIN; gaussdb=# CURSOR cursor2 WITH HOLD FOR SELECT * FROM tbl_test ORDER BY 1; --使用FETCH命令检索3行数据。 gaussdb=# FETCH FORWARD 3 FROM cursor2; c1 ---- 1 2 3 (3 rows) --和普通的游标不一样,结束事务后,带WITH HOLD属性的游标依然可以使用。 gaussdb=# END; gaussdb=# FETCH FORWARD 2 FROM cursor2; c1 ---- 4 5 (2 rows) --关闭游标。 gaussdb=# CLOSE cursor2; --删除。 gaussdb=# DROP TABLE tbl_test;