声明

定义一个游标

概要

  1. DECLARE name [BINARY] [INSENSITIVE] [NO SCROLL] CURSOR
  2. [{WITH | WITHOUT} HOLD]
  3. FOR query [FOR READ ONLY]

描述

DECLARE 允许用户创建游标,可以使用游标来从大查询中一次检索少量的行。游标可以使用FETCH返回文本数据或者二进制形式的数据。

普通游标以文本格式返回数据,和 SELECT 相同。由于数据本身以二进制格式存储,所以系统必须进行转换以产生文本格式。一旦信息以文本形式返回,客户端应用程序可能需要将其转换为二进制格式来操作它。另外,文本格式的数据通常比二进制格式大。二进制游标可以返回更容易地操作二进制形式数据。然而,如果用户打算以文本形式显示数据,则以文本形式检索数据将在客户端上节省一些精力。

例如,如果一个查询从一个整数列返回1,那么用户将获得带有默认有游标的字符串1,而使用二进制游标,用户将会获得一个包含该值内部表示的4字节字段(以大端字节顺序)。

应当仔细使用二进制游标,许多应用程序(包括psql)并不准备处理二进制游标,并希望以文本格式返回数据。

注意:

当客户端应用程序使用‘扩展查询’协议发出 FETCH 命令时,绑定协议信息指定数据是以文本还是二进制格式检索。此选项将覆盖游标定义的方式。因此,当使用扩展查询协议时,二进制游标的概念就会过时-任何游标都可以被视为是文本或二进制的。

可以在UPDATEDELETE 语句中的 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

SELECTVALUES 命令会提供供游标返回的行。

如果游标在 UPDATEDELETE 命令的 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 系统视图来查看所有可用的游标。

例子

声明一个游标:

  1. DECLARE mycursor CURSOR FOR SELECT * FROM mytable;

兼容性

SQL 标准只允许在嵌入式SQL和模块中使用游标。Greenplum数据库数据库允许交互式使用游标(interactively)。

Greenplum数据库没有实现有游标的 OPEN 语句。游标在声明时就被认为是打开的。

SQL 标准允许游标向前向后移动。所有Greenplum数据库游标仅向前移动(非滚动)。

二进制游标是Greenplum数据库扩展。

另见

CLOSE, DELETE, FETCH, MOVE, SELECT, UPDATE

上级话题: SQL命令参考