DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR query [ FOR { READ ONLY | UPDATE [ OF column [, ...] ] } ]
DECLARE 允许用户创建游标, 用于在一个大的查询里面检索少数几行数据。 使用 FETCH [fetch(7)],游标可以既可以返回文本也可以返回二进制格式。
通常游标返回文本格式,和 SELECT 生成的是一样的。 因为数据在系统内部是用二进制格式存储的, 系统必须对数据做一定转换以生成文本格式。 一旦数据是以文本形式返回,那么客户端应用需要把它们转换成二进制进行操作。 另外,文本格式一般都比对应的二进制格式占的存储空间大。 二进制游标给你返回内部二进制形态的数据。当然,如果你想以文本方式显示数据,那么以文本方式检索会为你节约很多客户端的工作。
比如,如果查询从一个整数列返回一个一, 在缺省的游标里你将获得一个字符串 1,而如果是一个二进制游标, 你将得到一个 4-字节的包含该数值内部形式的数值(大端序)。
游标应该小心使用二进制游标。一些用户应用如 psql 是不识别二进制游标的, 而且期望返回的数据是文本格式。
BINARY,INSENSITIVE,SCROLL 关键字可以以任何顺序出现。
如果没有声明 WITH HOLD,那么这个命令创建的游标只能在当前事务中使用。
Thus, DECLARE without WITH
HOLD is useless outside a transaction block: the cursor would
survive only to the completion of the statement. Therefore
PostgreSQL reports an error if this
command is used outside a transaction block.
使用
BEGIN [begin(7)],
COMMIT [commit(7)]
和
ROLLBACK [rollback(7)]
定义一个事务块。
如果声明了 WITH HOLD,并且创建该游标的事务成功提交, 那么游标还可以在同一会话随后的事务里访问。(但如果创建它的事务回滚,那么游标被删除。) 带着 WITH HOLD 创建的游标是用一个明确的 CLOSE 命令,或者是会话终止来关闭的。 在目前的实现里,由一个游标代表的行是被拷贝到一个临时文件或者内存区里的,这样他们就仍然可以在随后的事务中被访问。
在定义一个要用来向后抓取的游标的时候,我们应该声明 SCROLL 选项。 这个是 SQL 标准要求的。不过,为了和早期的版本兼容, PostgreSQL 在没有 SCROLL 的时候也允许向后抓取, 只要游标的查询计划简单得不需要额外的开销就可以支持它。 不过,我们建议应用开发人员不要依赖于使用没有带着 SCROLL 定义的游标的后向查找功能。如果声明了 NO SCROLL,那么不管怎样都会禁止向后抓取的功能。
在 SQL 标准中游标只能在嵌入 SQL (ESQL) 的应用中使用。 PostgreSQL 服务器没有一个明确的 OPEN 语句;一个游标被认为在定义时就已经打开了。 不过,PostgreSQL嵌入的 SQL 预编译器, ecpg, 支持 SQL92 习惯,包括那些和DECLARE和OPEN相关的语句。
定义一个游标:
DECLARE liahona CURSOR FOR SELECT * FROM films;
SQL 标准只允许在嵌入的 SQL 中和模块中使用游标。 PostgreSQL 允许交互地使用游标。
SQL 标准允许游标更新表数据。 所有 PostgreSQL 的游标都是只读的。
二进制游标是 PostgreSQL 扩展。