DECLARE
声明
定义一个游标
概要
DECLARE name [BINARY] [INSENSITIVE] [NO SCROLL] CURSOR [{WITH | WITHOUT} HOLD] FOR query [FOR READ ONLY]
描述
DECLARE 允许用户创建游标,可以使用游标来从大查询中一次检索少量的行。游标可以使用FETCH返回文本数据或者二进制形式的数据。
普通游标以文本格式返回数据,和 SELECT 相同。由于数据本身以二进制格式存储,所以系统必须进行转换以产生文本格式。一旦信息以文本形式返回,客户端应用程序可能需要将其转换为二进制格式来操作它。另外,文本格式的数据通常比二进制格式大。二进制游标可以返回更容易地操作二进制形式数据。然而,如果用户打算以文本形式显示数据,则以文本形式检索数据将在客户端上节省一些精力。
例如,如果一个查询从一个整数列返回1,那么用户将获得带有默认有游标的字符串1,而使用二进制游标,用户将会获得一个包含该值内部表示的4字节字段(以大端字节顺序)。
应当仔细使用二进制游标,许多应用程序(包括psql)并不准备处理二进制游标,并希望以文本格式返回数据。
当客户端应用程序使用‘扩展查询’协议发出 FETCH 命令时,绑定协议信息指定数据是以文本还是二进制格式检索。此选项将覆盖游标定义的方式。因此,当使用扩展查询协议时,二进制游标的概念就会过时-任何游标都可以被视为是文本或二进制的。
可以在UPDATE 或 DELETE 语句中的 WHERE CURRENT OF 子句中指定游标,以更新或删除表数据。 该 UPDATE 或 DELETE 语句只能在服务器上执行, 例如在交互式psql会话或脚本中。语言扩展(如PL/pgSQL)不支持可更新的游标。
参数
- name
- 要创建有游标的名字
- BINARY
- 使游标返回二进制数据而不是文本形式。
- INSENSITIVE
- 表示当数据存在时,指出游标检索的数据不受游标所指表的更新的影响。在Greenplum数据库,所有游标都不敏感。这个关键词目前没有任何效果,仅为了和SQL的表准的兼容。
- NO SCROLL
- 游标不能以非顺序方式检索行。这是Greenplum数据库中的默认行为,因为不支持可滚动的游标 (SCROLL)。
- WITH HOLD
- WITHOUT HOLD
- WITH HOLD 指出了该表可能会继续使用,在创建该游标的事务成功提交之后。WITHOUT HOLD 指出游标在脱离创建它的事务之后,就不能再使用了。默认值为 WITHOUT HOLD。
- WITH HOLD 不能指定,当 query 包含 FOR UPDATE 或 FOR SHARE 子句。
- query
- SELECT 或
VALUES
命令会提供供游标返回的行。
如果游标在 UPDATE 或 DELETE 命令的 WHERE CURRENT OF 子句中使用,该SELECT 命令必须要满足以下条件:
- 不能引用视图或者外部表
- 仅引用一张表
该表必须是可更新的,例如,以下是不可更新的:表函数,设置了返回值的函数,仅附加表,列表
- 不能包含任何以下的:
- 分组语句
- 例如 UNION ALL 或 UNION DISTINCT的集合操作
- 排序子句
- 窗口子句
- 连接或者左连接
指定 FOR UPDATE 子句在 SELECT 命令中可以阻止元组在获取和更新之间被其他会话更改行。没有该 FOR UPDATE 子句,那么随后(同会话中)带有WHERE CURRENT OF子句的 UPDATE 或 DELETE 命令就不起作用了,如果该行在创建游标之前已经更改(被其他会话更改)。(如数据删除之后用户去更新会找不到)
注意: 指定 FOR UPDATE 子句在 SELECT 命令中锁定的是整个表,而不是仅仅是用户选择的行。
- FOR READ ONLY
- FOR READ ONLY 指明该游标仅仅用于只读模式
注意
除非指定了 WITH HOLD,由该命令创建的游标只能在当前的事务中使用。因此,没有 WITH HOLD的DECLARE 语句,除非在事务块之外:否则该游标仅生存到该语句结束。因此如果该命令用于事务块之外,Greenplum数据库会报告了一个错误。使用 BEGIN,COMMIT 和 ROLLBACK 来定义一个事务块。
如果指定 WITH HOLD 而且创建有游标的事务成功提交,该游标能够继续被同一个会话中的子事务访问。(但是如果创建事务被终止,则该游标会被删除)创建的带有 WITH HOLD 的游标,当被发出明确的 CLOSE 指令或者在会话结束时就会关闭。在当前的实现中,由保留游标表示的行t被复制到临时文件或者存储区域中,以便他们可以用于后续的事务。
如果用户在事务中使用 DECLARE 创建了游标,用户不能在事务中使用 SET 命令直到用户用 CLOSE 命令关闭了游标。
Greenplum数据库不支持游标滚动。用户只能使用 FETCH 来向前移动游标,不能向后。
追加优化表不支持DECLARE...FOR UPDATE。
用户可以通过查询 pg_cursors 系统视图来查看所有可用的游标。
例子
声明一个游标:
DECLARE mycursor CURSOR FOR SELECT * FROM mytable;
兼容性
SQL 标准只允许在嵌入式SQL和模块中使用游标。Greenplum数据库数据库允许交互式使用游标(interactively)。
Greenplum数据库没有实现有游标的 OPEN 语句。游标在声明时就被认为是打开的。
SQL 标准允许游标向前向后移动。所有Greenplum数据库游标仅向前移动(非滚动)。
二进制游标是Greenplum数据库扩展。