DECLARE

Name

DECLARE -- 定义一个游标

Synopsis

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

描述

DECLARE允许一个用户来创建,这可以在较大查询的一个时间里 用来检索少量行。游标创建以后,通过使用FETCH可以将行抓取 出来。

Note: 这个页面在SQL命令水平描述了游标的使用方法。如果你视图使用PL/pgSQL 函数中的游标,规则就会不一样—请参阅Section 39.7

参数

name

将要创建的游标名

BINARY

令游标以二进制而不是文本格式返回数据

INSENSITIVE

指明从游标中恢复的数据应该是不受影响的,在有表创建以后通过更新游标下的表。 在PostgreSQL中,这是默认的相应;所以这个关键字 没有影响并且仅接受兼容SQL标准。

SCROLL
NO SCROLL

SCROLL声明该游标可以用于以倒序的方式检索数据行 (也就是反向检索)。根据查询的执行计划的不同,声明SCROLL 可能会对查询的执行时间有不良影响。NO SCROLL声明该游标不 能用于以倒序的方式检索数据行。缺省仅允许在某些情况下倒序检索,这不同于指定 SCROLL。参见 注意获取细节。

WITH HOLD
WITHOUT HOLD

WITH HOLD(缺省)声明该游标可以在创建它的事务成功提交后继续使用。 WITHOUT HOLD声明该游标不能在创建它的事务提交后使用。 r若WITHOUT HOLDWITH HOLD都未声明, 则默认为WITHOUT HOLD

query

一个SELECT或者VALUES命令 会提供游标返回的行。

BINARY,INSENSITIVE,SCROLL关键字 可以以任何顺序出现。

注意

正常的游标以文本格式返回数据,与SELECT产生的一样。BINARY选项声明 BINARY选项声明游标会返回二进制格式的数据。这减少了服务器端和客户端的转换工作, 但代价却是产生更多的处理基于平台的二进制数据格式的程序工作。 例如:如果一个查询返回一个来自整型列的一个数值,你会得到一个带有默认游标的1的 字符串,而通过一个二进制游标您会得到一个包含值的内部表达的4字节字段(按大端字节顺序)。

二进制游标应当谨慎使用。包括psql在内的许多应用,不准备处理二进制游标 并且希望数据以文本形式返回。

Note: 当客户端应用使用"extended query"协议来发布FETCH命令, Bind协议信息声明是以文本形式还是以二进制形式恢复数据。该选项重写游标定义 的方式。,当使用任何光标可以看作是文本或二进制扩展查询协议 —同样二 进制游标的概念因此过时。

除非声明WITH HOLD,否则由该命令创建的游标只能在当前事务内使用。 因此,不带有WITH HOLDDECLARE在事物块之外是无效的: 游标只能持续到语句完成。所以,若这样一个命令在一个事务块之外使用时,PostgreSQL 或报告一个错误。使用BEGINCOMMIT (或者ROLLBACK)来定义一个事务块。

如果声明了WITH HOLD并且创建该游标的事务成功提交,那么游标还可以在同一会话 随后的事务里访问。但如果创建它的事务回滚,那么游标被删除。带WITH HOLD创建 的游标是用一个明确的CLOSE命令或者是会话终止来关闭的。在目前的实现里,由一 个游标代表的行是被拷贝到一个临时文件或者内存区里的,这样他们就仍然可以在随后的事务中被访问。

当查询包括FOR UPDATE或者FOR SHAREWITH HOLD不会被声明。

在定义一个要用来反向抓取的游标的时候,应该声明SCROLL选项,这是 SQL 标准要求的。 不过,为了和早期的版本兼容,只要游标的查询计划简单得不需要额外的开销, PostgreSQL在没有声明SCROLL的时候也允许反向抓取。不过, 建议应用开发人员不要依赖于使用没有使用SCROLL定义的游标的反向查找功能。如果 声明了NO SCROLL,那么不管怎样都会禁止反向抓取的功能。

当查询包括FOR UPDATE或者FOR SHARE时,向读取也是不允许的; 所以在这种情况下可能不会声明SCROLL

Caution

滚动效果和WITH HOLD游标可能会给出意想不到的结果,如果他们 调用任何易失函数(参阅Section 35.6)。当一个已抓取的行 再次被抓取,函数可能会被重新执行,可能会导致不同于第一次的结果。针对该情况的 一个工作区是为了声明游标WITH HOLD并且在阅读其任意行之前提 交事务。这回强制游标的整个输出在临时表中实现,因此易失函数完全是为每一行执行一次。

若游标的查询包括FOR UPDATE或者FOR SHARE,那么返回的行会在他们首次 被抓取时锁定,与带有这些选项的定期SELECT命令以相同的方式。 另外,返回的行将是最新的版本;因此,这些选项提供SQL标准中称作"sensitive cursor" 的等价物。(声明带有FOR UPDATE或者FOR SHAREINSENSITIVE 是错误。)

Caution

若游标旨在与UPDATE ... WHERE CURRENT OF或者DELETE ... WHERE CURRENT OF 一起使用,那么通常建议使用FOR UPDATE。使用FOR UPDATE阻止其他会话 在其被抓去和更新之间的时间里改变行。没有FOR UPDATE,一个随后的 WHERE CURRENT OF命令将会没有效果,如果行在游标创建之后被改变。

使用FOR UPDATE的另一个原因是:没有它,一个随后的WHERE CURRENT OF 可能会失败,若游标查询不满足SQL标准对"simply updatable" 的规则(有钱,游标必须 仅参考一个表并且不使用分组或者ORDER BY)。不是简单可更新的游标可能会工作或者 不会工作,这由计划选择的详细情况决定;所以在最坏的情况下,一个应用程序可能测试工作并然后 在生产中失败。

不使用带有WHERE CURRENT OFFOR UPDATE的主要原因是:如果您 需要可卷动的游标,或者对后续更新不敏感(即继续显示旧数据)。若这是一个要求, 密切关注以上显示的警告。

SQL 标准中的游标只能在嵌入SQL(ESQL)的应用中使用。 PostgreSQL服务器没有一个明确的OPEN语句; 一个游标被认为在定义时就已经打开了。不过,PostgreSQL嵌入的 SQL 预编译器(ECPG)支持 SQL 标准的习惯,包括那些和 DECLAREOPEN相关的语句。

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

示例

定义一个游标:

DECLARE liahona CURSOR FOR SELECT * FROM films;

参阅FETCH获取有关游标使用的更多例子。 See FETCH for more examples of cursor usage.

兼容性

SQL标准认为游标是否对默认的底层数据的并发更新敏感是依赖实现决定的。 在PostgreSQL中,游标是默认不敏感的,并且 可以通过声明FOR UPDATE来使其敏感。其他产品可能以不同的方式工作。

SQL 标准只允许在嵌入的SQL中和模块中使用游标。 PostgreSQL允许交互地使用游标。

二进制游标是PostgreSQL扩展。

又见

CLOSE, FETCH, MOVE