PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

FETCH

FETCH — 使用游标从一个查询中取回行

Synopsis

FETCH [ direction ] [ FROM | IN ] cursor_name

where direction can be one of:

    NEXT
    PRIOR
    FIRST
    LAST
    ABSOLUTE count
    RELATIVE count
    count
    ALL
    FORWARD
    FORWARD count
    FORWARD ALL
    BACKWARD
    BACKWARD count
    BACKWARD ALL

描述

FETCH 使用先前创建的游标取回行。

游标有一个与之关联的位置,FETCH 会用到该位置。游标位置可以位于查询结果第一行之前、结果的某个特定行上,或者结果最后一行之后。游标刚创建时位于第一行之前。取回若干行之后,游标位于最近取回的那一行上。如果 FETCH 越过了可用行的末尾,游标就会被留在最后一行之后(如果是向后取行,则留在第一行之前)。FETCH ALL 或 FETCH BACKWARD ALL 总是会把游标留在最后一行之后或第一行之前。

NEXT、PRIOR、FIRST、LAST、ABSOLUTE、RELATIVE 这些形式会在适当地移动游标之后取回单行。如果不存在这样的行,则返回空结果,并且游标会视情况被留在第一行之前或最后一行之后。

使用 FORWARD 和 BACKWARD 的形式会沿向前或向后方向取回指定数量的行,并把游标留在最后返回的行上(如果 count 超过了可用行的数量,则留在所有行之后/之前)。

RELATIVE 0、FORWARD 0 和 BACKWARD 0 都会请求在不移动游标的情况下取回当前行,也就是重新取回最近取回的那一行。除非游标位于第一行之前或最后一行之后,否则这会成功;在后一种情况下,不会返回任何行。

Note

本页面描述在 SQL 命令层面对游标的使用。如果你试图在 PL/pgSQL 函数中使用游标,规则会有所不同 — 参见 Section 41.7.3。

参数

direction

direction 定义取数方向和要取的行数。它可以取以下值:

NEXT

取下一行。如果省略了 direction,这就是默认值。

PRIOR

取回前一行。

FIRST

取回查询的第一行(等同于 ABSOLUTE 1)。

LAST

取回查询的最后一行(等同于 ABSOLUTE -1)。

ABSOLUTE count

取回查询的第 count 行,或从末尾算起的第 abs(count) 行(如果 count 为负)。如果 count 超出范围,则位置会处于第一行之前或最后一行之后;特别地,ABSOLUTE 0 会定位到第一行之前。

RELATIVE count

取回第 count 个后继行,或第 abs(count) 个先前行(如果 count 为负)。RELATIVE 0 会重新取回当前行(如果有的话)。

count

取回接下来的 count 行(等同于 FORWARD count)。

ALL

取回所有剩余的行(等同于 FORWARD ALL)。

FORWARD

取回下一行(等同于 NEXT)。

FORWARD count

取回接下来的 count 行。FORWARD 0 会重新取回当前行。

FORWARD ALL

取回所有剩余的行。

BACKWARD

取回前一行(等同于 PRIOR)。

BACKWARD count

取回前面的 count 行(向后扫描)。BACKWARD 0 会重新取回当前行。

BACKWARD ALL

取回前面所有的行(向后扫描)。

count

count 是一个可以带符号的整数常量,它决定要取回的位置或行数。对于 FORWARD 和 BACKWARD 的情况,指定一个负的 count 等同于改变 FORWARD 和 BACKWARD 的方向。

cursor_name

一个已打开游标的名称。

输出

成功完成时,FETCH 命令会返回一个形式如下的命令标签

FETCH count

其中 count 是取回的行数(可能为零)。注意在 psql 中,这个命令标签实际上并不会被显示出来,因为 psql 会改为显示取回的行。

注记

游标应当在声明时带上 SCROLL 选项,如果你打算使用 FETCH 的任何变体,而不只是 FETCH NEXT 或带正数的 FETCH FORWARD。对于简单查询,PostgreSQL 会允许从没有用 SCROLL 声明的游标向后取行,但这种行为最好不要依赖。如果游标是用 NO SCROLL 声明的,则不允许任何向后取行。

ABSOLUTE 取行并不比用相对移动导航到目标行更快:底层实现反正必须遍历所有中间的行。负数的绝对取行甚至更糟:必须把查询读取到末尾才能找到最后一行,然后再从那里反向遍历。不过,倒回到查询的开头(例如 FETCH ABSOLUTE 0)是很快的。

DECLARE 用于定义游标。使用 MOVE 可以在不取回数据的情况下更改游标位置。

示例

下面的例子使用游标遍历一个表:

BEGIN WORK;

-- Set up a cursor:
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;

-- Fetch the first 5 rows in the cursor liahona:
FETCH FORWARD 5 FROM liahona;

 code  |          title          | did | date_prod  |   kind   |  len
-------+-------------------------+-----+------------+----------+-------
 BL101 | The Third Man           | 101 | 1949-12-23 | Drama    | 01:44
 BL102 | The African Queen       | 101 | 1951-08-11 | Romantic | 01:43
 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
 P_301 | Vertigo                 | 103 | 1958-11-14 | Action   | 02:08
 P_302 | Becket                  | 103 | 1964-02-03 | Drama    | 02:28

-- Fetch the previous row:
FETCH PRIOR FROM liahona;

 code  |  title  | did | date_prod  |  kind  |  len
-------+---------+-----+------------+--------+-------
 P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08

-- Close the cursor and end the transaction:
CLOSE liahona;
COMMIT WORK;

兼容性

SQL 标准定义的 FETCH 仅用于嵌入式 SQL。这里描述的 FETCH 变体会像 SELECT 的结果那样返回数据,而不是把数据放入宿主变量中。除了这一点之外,FETCH 与 SQL 标准完全向上兼容。

FETCH 中涉及 FORWARD 和 BACKWARD 的那些形式,以及 FETCH count 和 FETCH ALL(其中隐含了 FORWARD)这两种形式,都是 PostgreSQL 的扩展。

SQL 标准只允许在游标名之前使用 FROM;可以使用 IN 或者把它们完全省略的选项则是一种扩展。

另请参阅

CLOSE, DECLARE, MOVE