Note

DECLARE

DECLARE —定义一个游标

Synopsis

DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]
    CURSOR [ { WITH | WITHOUT } HOLD ] FOR query

Description

DECLARE允许用户创建游标,这些游标可用于一次从较大查询中检索少量行。创建游标后,使用FETCH从中获取行。

Note

本页在 SQL 命令级别描述游标的用法。如果您尝试在 PL/pgSQL 函数中使用游标,则规则有所不同—参见Section 42.7

Parameters

  • name

    • 要创建的游标的名称。
  • BINARY

    • 使光标返回二进制而不是文本格式的数据。
  • INSENSITIVE

    • 指示从游标中检索到的数据应不受创建游标后对游标基础表的更新的影响。在 PostgreSQL 中,这是默认行为。因此,此关键字无效,仅接受与 SQL 标准的兼容性。
  • SCROLL
    NO SCROLL

    • SCROLL指定可以使用游标以非连续方式(例如,向后)检索行。根据查询执行计划的复杂程度,指定SCROLL可能会影响查询的执行时间。 NO SCROLL指定不能使用游标以非 Sequences 方式检索行。默认情况下允许滚动。这与指定SCROLL不同。有关详情,请参见Notes
  • WITH HOLD
    WITHOUT HOLD

    • WITH HOLD指定在成功提交创建游标的事务后可以 continue 使用游标。 WITHOUT HOLD指定不能在创建游标的事务之外使用游标。如果未指定WITHOUT HOLDWITH HOLD,则默认为WITHOUT HOLD
  • query

    • SELECTVALUES命令,它将提供游标要返回的行。

关键字BINARYINSENSITIVESCROLL可以按任何 Sequences 出现。

Notes

普通游标以文本格式返回数据,与SELECT相同。 BINARY选项指定游标应以二进制格式返回数据。这减少了服务器和 Client 端的转换工作,但以程序员更多的精力来处理依赖于平台的二进制数据格式为代价。例如,如果查询从整数列返回值 1,则将使用默认游标获得1的字符串,而使用二进制游标将获得包含该值的内部表示形式的 4 字节字段(以大端字节序)。

二进制游标应谨慎使用。许多应用程序,包括 psql,都不准备处理二进制游标,并期望数据以文本格式返回。

Note

当 Client 端应用程序使用“扩展查询”协议发出FETCH命令时,绑定协议消息将指定是以文本还是二进制格式检索数据。此选择将覆盖定义光标的方式。因此,当使用扩展查询协议时,二进制游标的概念就已过时了-任何游标都可以视为文本或二进制。

除非指定WITH HOLD,否则此命令创建的游标只能在当前事务中使用。因此,DECLARE而不是WITH HOLD在事务块之外是无用的:游标将仅生存到语句完成。因此,如果在事务块外使用这样的命令,PostgreSQL 将报告错误。使用BEGINCOMMIT(或ROLLBACK)定义事务块。

如果指定了WITH HOLD并且成功提交了创建游标的事务,则该游标可以 continue 被同一会话中的后续事务访问。 (但是,如果创建事务被中止,则删除游标.)当在其上发出显式CLOSE命令或会话结束时,使用WITH HOLD创建的游标将关闭。在当前实现中,由保留的游标表示的行被复制到临时文件或存储区中,以便它们可用于后续事务。

当查询包含FOR UPDATEFOR SHARE时,不能指定WITH HOLD

定义用于向后取回的游标时,应指定SCROLL选项。这是 SQL 标准所必需的。但是,为了与早期版本兼容,如果游标的查询计划足够简单,不需要任何额外开销来支持它,则 PostgreSQL 将允许不使用SCROLL进行向后取回。但是,建议应用程序开发人员不要依赖未使用SCROLL创建的游标使用向后取回。如果指定NO SCROLL,则无论如何都不允许向后取。

当查询包含FOR UPDATEFOR SHARE时,也不允许向后抓取;因此在这种情况下可能无法指定SCROLL

Caution

如果可滚动游标和WITH HOLD游标调用任何易失函数(请参见Section 37.6),它们可能会产生意外结果。当重新获取先前获取的行时,这些函数可能会重新执行,可能导致结果与第一次有所不同。在这种情况下,一种解决方法是声明游标WITH HOLD并提交事务,然后再从中读取任何行。这将强制将光标的整个输出在临时存储中实现,以便对每行仅对易失函数执行一次。

如果游标的查询包含FOR UPDATEFOR SHARE,则返回的行在首次获取时将被锁定,其方式与带有这些选项的常规SELECT命令的方式相同。此外,返回的行将是最新版本;因此,这些选项提供了与 SQL 标准所谓的“敏感游标”等效的功能。 (同时指定INSENSITIVEFOR UPDATEFOR SHARE是错误的.)

Caution

如果要与UPDATE ... WHERE CURRENT OFDELETE ... WHERE CURRENT OF一起使用光标,通常建议使用FOR UPDATE。使用FOR UPDATE可防止其他会话在获取行和更新行之间更改行。没有FOR UPDATE,如果自创建游标以来更改了行,则随后的WHERE CURRENT OF命令将无效。

使用FOR UPDATE的另一个原因是,没有它,如果游标查询不符合 SQL 标准的“可简单更新”的规则,则随后的WHERE CURRENT OF可能会失败(特别是,游标必须仅引用一个表并且不使用分组或ORDER BY) 。根据计划选择的详细信息,不能简单更新的游标可能会起作用,也可能不会起作用。因此在最坏的情况下,应用程序可能会在测试中工作,然后在 Producing 失败。如果指定FOR UPDATE,则保证游标是可更新的。

不将FOR UPDATEWHERE CURRENT OF结合使用的主要原因是,如果您需要光标可滚动或对后续更新不敏感(即 continue 显示旧数据)。如果这是必需的,请密切注意上面显示的警告。

SQL 标准仅对嵌入式 SQL 中的游标进行规定。 PostgreSQL 服务器不为游标实现OPEN语句;当游标被声明时,它被认为是打开的。但是,ECPG 是 PostgreSQL 的嵌入式 SQL 预处理程序,支持标准的 SQL 游标约定,包括涉及DECLAREOPEN语句的约定。

您可以通过查询pg_cursors系统视图来查看所有可用的游标。

Examples

声明游标:

DECLARE liahona CURSOR FOR SELECT * FROM films;

有关游标用法的更多示例,请参见FETCH

Compatibility

SQL 标准说,默认情况下,游标是否对基础数据的并发更新敏感,这取决于实现。在 PostgreSQL 中,游标默认情况下是不敏感的,可以通过指定FOR UPDATE使其敏感。其他产品可能会有所不同。

SQL 标准仅允许在嵌入式 SQL 和模块中使用游标。 PostgreSQL 允许交互使用游标。

二进制游标是 PostgreSQL 扩展。

See Also

CLOSE, FETCH, MOVE