===== FETCH ===== .. container:: refentry :name: SQL-FETCH .. container:: titlepage .. container:: refnamediv .. rubric:: FETCH :name: fetch FETCH — 使用游标从查询中检索行 .. container:: refsynopsisdiv .. rubric:: 大纲 :name: 大纲 .. code:: synopsis FETCH [ direction [ FROM | IN ] ] cursor_name 其中 direction 可以为空或者以下之一: NEXT PRIOR FIRST LAST ABSOLUTE count RELATIVE count count ALL FORWARD FORWARD count FORWARD ALL BACKWARD BACKWARD count BACKWARD ALL .. container:: refsect1 :name: id-1.9.3.149.6 .. rubric:: 描述 :name: 描述 ``FETCH``\ 从之前创建的一个游标中检索行。 游标具有一个相关联的位置,\ ``FETCH``\ 会用到该位置。 游标位置可能会位于查询结果的第一行之前、结果中任意行之上或者 结果的最后一行之后。在被创建时,游标被定位在第一行之前。在取出 一些行后,该游标被定位在最近被取出的行上。如果 ``FETCH``\ 运行超过了可用行的末尾,则该游标会被定位 在最后一行之后(如果向后取,则是第一行之前)。 ``FETCH ALL``\ 或者\ ``FETCH BACKWARD ALL``\ 将总是让游标被定位于最后一行之后或者第一行之前。 ``NEXT``\ 、\ ``PRIOR``\ 、\ ``FIRST``\ 、 ``LAST``\ 、\ ``ABSOLUTE``\ 、\ ``RELATIVE`` 形式会在适当移动游标后取出一行。如果没有这样一行,将返回一个空 结果,并且视情况将游标定位在第一行之前或者最后一行之后。 使用\ ``FORWARD``\ 和\ ``BACKWARD``\ 的形式会在 向前移动或者向后移动的方向上检索指定数量的行,然后将游标定位在 最后返回的行上(如果\ ``count``\ 超过可用的行数,则定位 在所有行之后或者之前)。 ``RELATIVE 0``\ 、\ ``FORWARD 0``\ 以及 ``BACKWARD 0``\ 都会请求检索当前行但不移动游标,也就是 重新取最近被取出的行。 只要游标没有被定位在第一行之前或者最后一行 之后,这种操作都会成功,否则不会返回任何行。 .. note:: .. rubric:: 注意 :name: 注意 :class: title 这个页面描述在 SQL 命令层面上对游标的使用。如果想要在 PL/pgSQL函数中使用游标,规则会有所不同 。 .. container:: refsect1 :name: id-1.9.3.149.7 .. rubric:: 参数 :name: 参数 .. container:: variablelist ``direction`` ``direction`` 定义获取方向以及要取得的行数。它可以是下列之一: .. container:: variablelist ``NEXT`` 取出下一行。如果省略\ ``direction``\ ,这将是默认值。 ``PRIOR`` 取出当前位置之前的一行。 ``FIRST`` 取出该查询的第一行(和\ ``ABSOLUTE 1``\ 相同)。 ``LAST`` 取出该查询的最后一行(和\ ``ABSOLUTE -1``\ 相同)。 ``ABSOLUTE count`` 取出该查询的第\ ``count``\ 个行,如果\ ``count``\ 为负则是从尾部开始取出 第\ ``abs(count``)个行。如果 ``count``\ 超出范围,将定位在第一行 之前或者最后一行之后。特别地,\ ``ABSOLUTE 0`` 会定位在第一行之前。 ``RELATIVE count`` 取出第\ ``count``\ 个后继行,如果 ``count``\ 为负 则是取出前面的第\ ``abs(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``\ he ``BACKWARD``\ 的意义。 ``cursor_name`` 一个已打开游标的名称。 .. container:: refsect1 :name: id-1.9.3.149.8 .. rubric:: 输出 :name: 输出 如果成功完成,\ ``FETCH``\ 命令返回一个下面形式的命令标签: .. code:: screen FETCH count ``count``\ 是取得的行数(可能 为零)。注意在psql中,命令标签将不会实际显示, 因为psql会显示被取得的行。 .. container:: refsect1 :name: id-1.9.3.149.9 .. rubric:: 注解 :name: 注解 如果想要使用\ ``FETCH``\ 的任意变体而不使用带有正计数的 ``FETCH NEXT``\ 或者\ ``FETCH FORWARD``\ , 应该用\ ``SCROLL``\ 声明游标。对于简单查询, PostgreSQL将允许从不带 ``SCROLL``\ 的游标中反向取得行,但最好不要依赖这种行为。 如果游标被声明为带有\ ``SCROLL``\ ,则不允许反向取得。 用\ ``ABSOLUTE``\ 取行并不比用相对移动快多少:不管则样, 底层实现都必须遍历所有的中间行。用负绝对值获取的情况更糟:必须读到 查询尾部来找到最后一行,并且接着从那里反向开始遍历。不过,回卷到查询 的开始(正如\ ``FETCH ABSOLUTE 0``\ )是很快的。 `DECLARE `__\ 被用来定义游标。使用 `MOVE `__\ 可改变游标位置而不检索数据。 .. container:: refsect1 :name: id-1.9.3.149.10 .. rubric:: 示例 :name: 示例 下面的例子用一个游标遍历一个表: .. code:: programlisting BEGIN WORK; -- 建立一个游标: DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films; -- 在游标 liahona 中取出前 5 行: 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 PRIOR FROM liahona; code | title | did | date_prod | kind | len -------+---------+-----+------------+--------+------- P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 -- 关闭游标并且结束事务: CLOSE liahona; COMMIT WORK; .. container:: refsect1 :name: id-1.9.3.149.11 .. rubric:: 兼容性 :name: 兼容性 SQL 标准只定义\ ``FETCH``\ 在嵌入式 SQL 中使用。 这里描述的\ ``FETCH``\ 变体返回数据时就好像数据是 一个\ ``SELECT``\ 结果,而不是被放在主变量中。 除这一点之外,\ ``FETCH``\ 完全向上兼容于 SQL 标准。 涉及\ ``FORWARD``\ 和\ ``BACKWARD``\ 的 ``FETCH``\ 形式,以及形式\ ``FETCH count``\ 和\ ``FETCH ALL``\ (其中\ ``FORWARD``\ 是隐式的)都是 PostgreSQL扩展。 SQL 标准只允许\ ``FROM``\ 在游标名之前。使用 ``IN``\ 的选项或者完全省去它们是一种扩展。 .. container:: refsect1 :name: id-1.9.3.149.12 .. rubric:: 另见 :name: 另见 `CLOSE `__, `DECLARE `__, `MOVE `__