バージョンごとのドキュメント一覧

41.7. カーソル #

<title>Cursors</title>

Rather than executing a whole query at once, it is possible to set up a <firstterm>cursor</firstterm> that encapsulates the query, and then read the query result a few rows at a time. One reason for doing this is to avoid memory overrun when the result contains a large number of rows. (However, <application>PL/pgSQL</application> users do not normally need to worry about that, since <literal>FOR</literal> loops automatically use a cursor internally to avoid memory problems.) A more interesting usage is to return a reference to a cursor that a function has created, allowing the caller to read the rows. This provides an efficient way to return large row sets from functions. 問い合わせ全体を一度に実行するのではなく、カーソルを設定して、問い合わせをカプセル化し、問い合わせの結果を一度に数行ずつ読み取ることができます。 これを行う理由の1つは、結果内に多数の行がある場合のメモリの枯渇を防ぐことです。 (しかし、PL/pgSQLユーザは通常これを心配する必要はありません。 FORループは自動的にカーソルを内部的に使用してメモリの問題を防ぐからです。) より興味深い使用方法として、呼び出し元が行を読み取ることをできるように、作成されたカーソルへの参照を返す方法があります。 これにより、関数から大量の行集合を返す際の効率が向上します。

41.7.1. カーソル変数の宣言 #

<title>Declaring Cursor Variables</title>

All access to cursors in <application>PL/pgSQL</application> goes through cursor variables, which are always of the special data type <type>refcursor</type>. One way to create a cursor variable is just to declare it as a variable of type <type>refcursor</type>. Another way is to use the cursor declaration syntax, which in general is: PL/pgSQLにおけるカーソルへのアクセスは全て、カーソル変数を経由します。 カーソル変数は、常に特殊なrefcursorデータ型です。 カーソル変数を作成する1つの方法は、単にrefcursor型の変数として宣言することです。 他の方法は、カーソル宣言構文を使用することです。 以下にその一般形を示します。

name [ [ NO ] SCROLL ] CURSOR [ ( arguments ) ] FOR query;

(<literal>FOR</literal> can be replaced by <literal>IS</literal> for <productname>Oracle</productname> compatibility.) If <literal>SCROLL</literal> is specified, the cursor will be capable of scrolling backward; if <literal>NO SCROLL</literal> is specified, backward fetches will be rejected; if neither specification appears, it is query-dependent whether backward fetches will be allowed. <replaceable>arguments</replaceable>, if specified, is a comma-separated list of pairs <literal><replaceable>name</replaceable> <replaceable>datatype</replaceable></literal> that define names to be replaced by parameter values in the given query. The actual values to substitute for these names will be specified later, when the cursor is opened. Oracleとの互換性のため、FORISに置き換えることができます。) もしSCROLLを指定すれば、カーソルは逆方向に移動できます。 もしNO SCROLLを指定すれば、逆方向の行の取り出しはできません。 どちらも指定しない時、逆方向に取り出しできるかは問い合わせに依存します。 もしargumentsがあれば、name datatypeをカンマで区切ったリストで、与えられた問い合わせ内のパラメータ値として置換される名前を定義します。 その名前に実際に置換される値は、カーソルを開いた時点より後に指定されます。

Some examples: 以下に例を示します。

DECLARE
    curs1 refcursor;
    curs2 CURSOR FOR SELECT * FROM tenk1;
    curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;

All three of these variables have the data type <type>refcursor</type>, but the first can be used with any query, while the second has a fully specified query already <firstterm>bound</firstterm> to it, and the last has a parameterized query bound to it. (<literal>key</literal> will be replaced by an integer parameter value when the cursor is opened.) The variable <literal>curs1</literal> is said to be <firstterm>unbound</firstterm> since it is not bound to any particular query. これら3つの変数は全てrefcursorデータ型を持ちますが、最初のものは全ての問い合わせに使用でき、2番目には完全な問い合わせが既にバインドされています(結び付けられています)。 また、最後のものには、パラメータ付きの問い合わせがバインドされています (keyはカーソルが開いた時に整数パラメータ値に置き換えられます)。 curs1変数は、特定の問い合わせに結び付けられていませんので、バインドされていないと呼ばれます。

The <literal>SCROLL</literal> option cannot be used when the cursor's query uses <literal>FOR UPDATE/SHARE</literal>. Also, it is best to use <literal>NO SCROLL</literal> with a query that involves volatile functions. The implementation of <literal>SCROLL</literal> assumes that re-reading the query's output will give consistent results, which a volatile function might not do. カーソルの問い合わせがFOR UPDATE/SHAREを使っている場合、SCROLLオプションは使えません。 また、揮発性の関数を伴う問い合わせにはNO SCROLLを使うことが最善です。 SCROLLの実装は、問い合わせの出力を再読み込みすると一貫した結果が返えることを仮定していて、これは揮発性の関数ではそうではありません。

41.7.2. カーソルを開く #

<title>Opening Cursors</title>

Before a cursor can be used to retrieve rows, it must be <firstterm>opened</firstterm>. (This is the equivalent action to the SQL command <link linkend="sql-declare"><command>DECLARE CURSOR</command></link>.) <application>PL/pgSQL</application> has three forms of the <command>OPEN</command> statement, two of which use unbound cursor variables while the third uses a bound cursor variable. カーソルを使用して行を取り出す前に、カーソルは開かれる必要があります。 (これはDECLARE CURSOR SQLコマンドの動作と同じです。) PL/pgSQLには3種類のOPEN文があり、そのうちの2つはバインドされていないカーソル変数を使用し、残りの1つはバインドされたカーソル変数を使用します。

注記

Bound cursor variables can also be used without explicitly opening the cursor, via the <command>FOR</command> statement described in <xref linkend="plpgsql-cursor-for-loop"/>. A <command>FOR</command> loop will open the cursor and then close it again when the loop completes. バインドされたカーソル変数は41.7.4で説明されているFOR文で、明示的にカーソルを開かなくても使用できます。 FORループはカーソルを開き、ループが完了すると再び閉じます。

Opening a cursor involves creating a server-internal data structure called a <firstterm>portal</firstterm>, which holds the execution state for the cursor's query. A portal has a name, which must be unique within the session for the duration of the portal's existence. By default, <application>PL/pgSQL</application> will assign a unique name to each portal it creates. However, if you assign a non-null string value to a cursor variable, that string will be used as its portal name. This feature can be used as described in <xref linkend="plpgsql-cursor-returning"/>. カーソルを開くと、ポータルと呼ばれるサーバ内部のデータ構造が作成されます。ポータルは、カーソルの問い合わせの実行状態を保持します。 ポータルには名前があり、ポータルの存続期間中はセッション内で一意でなければなりません。 デフォルトでは、PL/pgSQLは作成する各ポータルに一意の名前を割り当てます。 しかし、カーソル変数にNULL文字列以外の値を割り当てると、その文字列がポータル名として使用されます。 この機能は41.7.3.5で説明するように使うことができます。

41.7.2.1. OPEN FOR query #

OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR query;

The cursor variable is opened and given the specified query to execute. The cursor cannot be open already, and it must have been declared as an unbound cursor variable (that is, as a simple <type>refcursor</type> variable). The query must be a <command>SELECT</command>, or something else that returns rows (such as <command>EXPLAIN</command>). The query is treated in the same way as other SQL commands in <application>PL/pgSQL</application>: <application>PL/pgSQL</application> variable names are substituted, and the query plan is cached for possible reuse. When a <application>PL/pgSQL</application> variable is substituted into the cursor query, the value that is substituted is the one it has at the time of the <command>OPEN</command>; subsequent changes to the variable will not affect the cursor's behavior. The <literal>SCROLL</literal> and <literal>NO SCROLL</literal> options have the same meanings as for a bound cursor. カーソル変数は開かれ、実行するよう指定した問い合わせが付与されます。 既に開いたカーソルを開くことはできず、また、バインドされていないカーソル変数として(つまり、単なるrefcursor変数として)宣言されていなければなりません。 この問い合わせはSELECT文であるか、または(EXPLAINのように)何らかの行を返すものでなければなりません。 この問い合わせは、他のPL/pgSQLのSQL文と同様の方法で扱われます。 PL/pgSQLの変数名は置き換えられ、問い合わせ計画は再利用できるようにキャッシュされます。 PL/pgSQL変数がカーソルを使用する問い合わせに代入された時、変数はOPEN時の値となり、その後の変更はカーソルの動きに影響しません。 SCROLLおよびNO SCROLLオプションの意味はバインドされたカーソルと同様です。

An example: 以下に例を示します。

OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey;

41.7.2.2. OPEN FOR EXECUTE #

OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR EXECUTE query_string
                                     [ USING expression [, ... ] ];

The cursor variable is opened and given the specified query to execute. The cursor cannot be open already, and it must have been declared as an unbound cursor variable (that is, as a simple <type>refcursor</type> variable). The query is specified as a string expression, in the same way as in the <command>EXECUTE</command> command. As usual, this gives flexibility so the query plan can vary from one run to the next (see <xref linkend="plpgsql-plan-caching"/>), and it also means that variable substitution is not done on the command string. As with <command>EXECUTE</command>, parameter values can be inserted into the dynamic command via <literal>format()</literal> and <literal>USING</literal>. The <literal>SCROLL</literal> and <literal>NO SCROLL</literal> options have the same meanings as for a bound cursor. カーソル変数は開かれ、実行するよう指定した問い合わせが付与されます。 既に開いたカーソルを開くことはできず、また、バインドされていないカーソル変数として(つまり、単なるrefcursor変数として)宣言されていなければなりません。 問い合わせは、EXECUTEコマンドと同じ方法による文字列式として指定されます。 通常と同様に、これにより、次回に実行する際に違った問い合わせを計画できる柔軟性が得られます(41.11.2参照)。 また、変数置換がコマンド文字列上で行われないことも意味します。 EXECUTEと同様にformat()USINGを介して動的コマンドにパラメータ値を挿入することができます。 SCROLLおよびNO SCROLLオプションの意味はバインドされたカーソルと同様です。

An example: 以下に例を示します。

OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING keyvalue;

In this example, the table name is inserted into the query via <function>format()</function>. The comparison value for <literal>col1</literal> is inserted via a <literal>USING</literal> parameter, so it needs no quoting. この例では、テーブル名は問い合わせにformat()で挿入されています。 col1との比較値はUSING経由で埋め込まれますので、引用符を付ける必要がありません。

41.7.2.3. バインドされたカーソルを開く #

<title>Opening a Bound Cursor</title>
OPEN bound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ];

This form of <command>OPEN</command> is used to open a cursor variable whose query was bound to it when it was declared. The cursor cannot be open already. A list of actual argument value expressions must appear if and only if the cursor was declared to take arguments. These values will be substituted in the query. 宣言時に問い合わせが結び付いたカーソル変数を開くために使用されるOPENの形式です。 既に開いたカーソルを開くことはできません。 実引数の式のリストはカーソルが引数を取るものと宣言された場合にのみ現れます。 これらの値は問い合わせの中で置き換えられます。

The query plan for a bound cursor is always considered cacheable; there is no equivalent of <command>EXECUTE</command> in this case. Notice that <literal>SCROLL</literal> and <literal>NO SCROLL</literal> cannot be specified in <command>OPEN</command>, as the cursor's scrolling behavior was already determined. バインドされたカーソルの問い合わせ計画は常にキャッシュ可能とみなされます。 この場合、EXECUTEと等価なものはありません。 SCROLLおよびNO SCROLLOPENにおいて指定できないことに注意してください。 カーソル移動の仕様はすでに決まっているからです。

Argument values can be passed using either <firstterm>positional</firstterm> or <firstterm>named</firstterm> notation. In positional notation, all arguments are specified in order. In named notation, each argument's name is specified using <literal>:=</literal> to separate it from the argument expression. Similar to calling functions, described in <xref linkend="sql-syntax-calling-funcs"/>, it is also allowed to mix positional and named notation. 位置的表記または記名的表記を使用して、引数の値を渡すことができます。 位置的表記では、全ての引数が順番に指定されます。 記名的表記では、引数の式と区別するために:=を使用して、各々の引数の名前が指定されます。 4.3に記述した関数呼び出しと同様に、位置的表記と記名的表記を混用できます。

Examples (these use the cursor declaration examples above): 例を示します(ここでは上例のカーソル宣言を使用します)。

OPEN curs2;
OPEN curs3(42);
OPEN curs3(key := 42);

Because variable substitution is done on a bound cursor's query, there are really two ways to pass values into the cursor: either with an explicit argument to <command>OPEN</command>, or implicitly by referencing a <application>PL/pgSQL</application> variable in the query. However, only variables declared before the bound cursor was declared will be substituted into it. In either case the value to be passed is determined at the time of the <command>OPEN</command>. For example, another way to get the same effect as the <literal>curs3</literal> example above is 変数の代入はバインドされたカーソルの問い合わせで行われるため、カーソルへ値を渡す方法が2つあります。 OPENコマンドの明確な引数とするものと、問い合わせにおけるPL/pgSQL変数として暗黙的に参照するものです。 しかし、バインドされたカーソルの宣言より前に宣言した変数だけが代入されます。 どちらの場合も、OPENの実行時に変数値が決まります。 例えば、上例のcurs3と同じ結果を取得する方法を、以下に示します。

DECLARE
    key integer;
    curs4 CURSOR FOR SELECT * FROM tenk1 WHERE unique1 = key;
BEGIN
    key := 42;
    OPEN curs4;

41.7.3. カーソルの使用 #

<title>Using Cursors</title>

Once a cursor has been opened, it can be manipulated with the statements described here. カーソルを開いてから、ここで説明する文を使用してカーソルを扱うことができます。

These manipulations need not occur in the same function that opened the cursor to begin with. You can return a <type>refcursor</type> value out of a function and let the caller operate on the cursor. (Internally, a <type>refcursor</type> value is simply the string name of the portal containing the active query for the cursor. This name can be passed around, assigned to other <type>refcursor</type> variables, and so on, without disturbing the portal.) これらの操作は、カーソルを開始するために開いた関数内で行う必要はありません。 関数からrefcursor値を返し、呼び出し元でそのカーソルの操作をさせることもできます。 (内部的にはrefcursor値は、カーソルへの有効な問い合わせを持つポータルの名前を示す単なる文字列です。 この名前は、ポータルを壊すことなく、他のrefcursor型の変数に渡したり、代入したりすることなどができます。)

All portals are implicitly closed at transaction end. Therefore a <type>refcursor</type> value is usable to reference an open cursor only until the end of the transaction. 全てのポータルは、暗黙的にトランザクションの終わりで閉ざされます。 したがって、refcursor値はそのトランザクションの終わりまでの間のみ開いたカーソルへの参照として有効です。

41.7.3.1. FETCH #

FETCH [ direction { FROM | IN } ] cursor INTO target;

<command>FETCH</command> retrieves the next row (in the indicated direction) from the cursor into a target, which might be a row variable, a record variable, or a comma-separated list of simple variables, just like <command>SELECT INTO</command>. If there is no suitable row, the target is set to NULL(s). As with <command>SELECT INTO</command>, the special variable <literal>FOUND</literal> can be checked to see whether a row was obtained or not. If no row is obtained, the cursor is positioned after the last row or before the first row, depending on the movement direction. FETCHSELECT INTOと同様に、カーソルから次の行を(指定された方向に)抽出し、対象に格納します。 対象とは、行変数、レコード変数、または単純な変数をカンマで区切ったリストです。 適切な行がない場合、ターゲットはNULLに設定されます。 SELECT INTOの場合と同様、特殊なFOUND変数を検査することで、行が取得できたかどうかを確認できます。 行が取得されない場合、カーソルは移動方向に応じて最後の行の後または最初の行の前に位置します。

The <replaceable>direction</replaceable> clause can be any of the variants allowed in the SQL <xref linkend="sql-fetch"/> command except the ones that can fetch more than one row; namely, it can be direction句は複数行を取り出すことができるコマンドを除き、SQL FETCHで許可されたどのようなコマンドも可能です。 すなわち、以下のものです。 NEXT, PRIOR, FIRST, LAST, ABSOLUTE count, RELATIVE count, <literal>FORWARD</literal>, or FORWARDまたは BACKWARD. Omitting <replaceable>direction</replaceable> is the same as specifying <literal>NEXT</literal>. In the forms using a <replaceable>count</replaceable>, the <replaceable>count</replaceable> can be any integer-valued expression (unlike the SQL <command>FETCH</command> command, which only allows an integer constant). <replaceable>direction</replaceable> values that require moving backward are likely to fail unless the cursor was declared or opened with the <literal>SCROLL</literal> option. direction句の省略は、NEXTの指定と同じです。 countを使う形式では、countはいかなる整数値の式も可能です。(SQL FETCHコマンドとは異なります。あちらは整数定数のみを受け付けます。) SCROLLオプションを用いてカーソルを宣言または開かないと、directionの値による逆方向への移動の要求は失敗します。

<replaceable>cursor</replaceable> must be the name of a <type>refcursor</type> variable that references an open cursor portal. cursor名は、開いているカーソルのポータルを参照するrefcursor変数名でなければなりません。

Examples: 例:

FETCH curs1 INTO rowvar;
FETCH curs2 INTO foo, bar, baz;
FETCH LAST FROM curs3 INTO x, y;
FETCH RELATIVE -2 FROM curs4 INTO x;

41.7.3.2. MOVE #

MOVE [ direction { FROM | IN } ] cursor;

<command>MOVE</command> repositions a cursor without retrieving any data. <command>MOVE</command> works like the <command>FETCH</command> command, except it only repositions the cursor and does not return the row moved to. The <replaceable>direction</replaceable> clause can be any of the variants allowed in the SQL <xref linkend="sql-fetch"/> command, including those that can fetch more than one row; the cursor is positioned to the last such row. (However, the case in which the <replaceable>direction</replaceable> clause is simply a <replaceable>count</replaceable> expression with no key word is deprecated in <application>PL/pgSQL</application>. That syntax is ambiguous with the case where the <replaceable>direction</replaceable> clause is omitted altogether, and hence it may fail if the <replaceable>count</replaceable> is not a constant.) As with <command>SELECT INTO</command>, the special variable <literal>FOUND</literal> can be checked to see whether there was a row to move to. If there is no such row, the cursor is positioned after the last row or before the first row, depending on the movement direction. MOVEコマンドは、データを取り出さないでカーソルの位置を変更します。 MOVEコマンドは、移動先の行を返さないでカーソルの位置だけを変更することを除けば、FETCHコマンドと同様の働きをします。 direction句は、SQL FETCHコマンドで許可されるどのような形式も可能で、複数行を取り出すことができるものも含まれます。 カーソルはそのような行の最後に位置します。 (しかし、direction句が単にキーワードのないcount式である場合は、PL/pgSQLでは非推奨です。 この構文は、direction句がすべて省略された場合との区別が曖昧であるため、countが定数でない場合は失敗する可能性があります。) SELECT INTOと同様に、特殊な変数FOUNDを用いて、移動先に行が存在するかどうかを検査できます。 そのような行がない場合、カーソルは移動方向に応じて最後の行の後または最初の行の前に位置します。

Examples: 例:

MOVE curs1;
MOVE LAST FROM curs3;
MOVE RELATIVE -2 FROM curs4;
MOVE FORWARD 2 FROM curs4;

41.7.3.3. UPDATE/DELETE WHERE CURRENT OF #

UPDATE table SET ... WHERE CURRENT OF cursor;
DELETE FROM table WHERE CURRENT OF cursor;

When a cursor is positioned on a table row, that row can be updated or deleted using the cursor to identify the row. There are restrictions on what the cursor's query can be (in particular, no grouping) and it's best to use <literal>FOR UPDATE</literal> in the cursor. For more information see the <xref linkend="sql-declare"/> reference page. カーソルの位置をテーブルの行に変更すれば、カーソルによって特定した行を更新または消去できます。 カーソル問い合わせは何が許されているのか(特にグループ化しないとき)についての制限があり、それはカーソル内でFOR UPDATEを使用することが最善です。 より詳細についてはDECLAREマニュアルページを参照下さい。

An example: 以下に例を示します。

UPDATE foo SET dataval = myval WHERE CURRENT OF curs1;

41.7.3.4. CLOSE #

CLOSE cursor;

<command>CLOSE</command> closes the portal underlying an open cursor. This can be used to release resources earlier than end of transaction, or to free up the cursor variable to be opened again. CLOSEは、開いているカーソルの背後にあるポータルを閉じます。 これを使用してトランザクションの終わりよりも前にリソースを解放することができ、また、カーソル変数を解放し、再度開くことができます。

An example: 例:

CLOSE curs1;

41.7.3.5. カーソルを返す #

<title>Returning Cursors</title>

<application>PL/pgSQL</application> functions can return cursors to the caller. This is useful to return multiple rows or columns, especially with very large result sets. To do this, the function opens the cursor and returns the cursor name to the caller (or simply opens the cursor using a portal name specified by or otherwise known to the caller). The caller can then fetch rows from the cursor. The cursor can be closed by the caller, or it will be closed automatically when the transaction closes. PL/pgSQL関数では、呼び出し元にカーソルを返すことができます。 この方法は、関数から複数行または複数列を返す場合、特にその結果集合が非常に大きい場合に有用です。 これを行うには、関数はカーソルを開き、呼び出し元にカーソル名を返します(もしくは、もし呼び出し元でポータル名がわかっていれば、単純に指定されたポータル名を使用してカーソルを開きます)。 これにより、呼び出し元はカーソルから行を取り出すことができるようになります。 カーソルは呼び出し元で閉じることができます。 または、トランザクションが終了した際に自動的に閉じられます。

The portal name used for a cursor can be specified by the programmer or automatically generated. To specify a portal name, simply assign a string to the <type>refcursor</type> variable before opening it. The string value of the <type>refcursor</type> variable will be used by <command>OPEN</command> as the name of the underlying portal. However, if the <type>refcursor</type> variable's value is null (as it will be by default), then <command>OPEN</command> automatically generates a name that does not conflict with any existing portal, and assigns it to the <type>refcursor</type> variable. カーソル用のポータル名は、プログラマが指定するか、または自動的に生成されます。 ポータル名を指定するには、開く前に、単にrefcursor変数に文字列を代入します。 refcursor変数の文字列値はOPENによって、背後のポータル名として使用されます。 しかし、refcursor変数の値がNULLの場合(デフォルトではそうなっています)、OPENは自動的に既存のポータルと競合しない名前を生成し、それをrefcursor変数に代入します。

注記

Prior to <productname>PostgreSQL</productname> 16, bound cursor variables were initialized to contain their own names, rather than being left as null, so that the underlying portal name would be the same as the cursor variable's name by default. This was changed because it created too much risk of conflicts between similarly-named cursors in different functions. PostgreSQL 16以前は、バインドされたカーソル変数は、NULLではなく自身の名前を含むように初期化されていました。そのため、背後にあるポータル名はデフォルトでカーソル変数の名前と同じになっていました。 これは、異なる関数内の同じような名前のカーソル間で競合するリスクがあまりにも大きくなるため、変更されました。

The following example shows one way a cursor name can be supplied by the caller: 以下の例は、呼び出し元でカーソル名を指定する方法を示しています。

CREATE TABLE test (col text);
INSERT INTO test VALUES ('123');

CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
BEGIN
    OPEN $1 FOR SELECT col FROM test;
    RETURN $1;
END;
' LANGUAGE plpgsql;

BEGIN;
SELECT reffunc('funccursor');
FETCH ALL IN funccursor;
COMMIT;

The following example uses automatic cursor name generation: 以下の例では、自動的に生成されたカーソル名を使用しています。

CREATE FUNCTION reffunc2() RETURNS refcursor AS '
DECLARE
    ref refcursor;
BEGIN
    OPEN ref FOR SELECT col FROM test;
    RETURN ref;
END;
' LANGUAGE plpgsql;


&#45;- need to be in a transaction to use cursors.

-- カーソルを使用するには、トランザクション内部である必要があります。
BEGIN;
SELECT reffunc2();

      reffunc2
--------------------
 <unnamed cursor 1>
(1 row)

FETCH ALL IN "<unnamed cursor 1>";
COMMIT;

The following example shows one way to return multiple cursors from a single function: 以下の例は単一関数から複数のカーソルを返す方法を示しています。

CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
BEGIN
    OPEN $1 FOR SELECT * FROM table_1;
    RETURN NEXT $1;
    OPEN $2 FOR SELECT * FROM table_2;
    RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;


&#45;- need to be in a transaction to use cursors.

-- カーソルを使用するには、トランザクション内部である必要があります。
BEGIN;

SELECT * FROM myfunc('a', 'b');

FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;

41.7.4. カーソル結果に対するループ #

<title>Looping through a Cursor's Result</title>

There is a variant of the <command>FOR</command> statement that allows iterating through the rows returned by a cursor. The syntax is: カーソルで返される行に対して反復することができるFOR文の亜種があります。 構文は以下のようになります。

[ <<label>> ]
FOR recordvar IN bound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ] LOOP
    statements
END LOOP [ label ];

The cursor variable must have been bound to some query when it was declared, and it <emphasis>cannot</emphasis> be open already. The <command>FOR</command> statement automatically opens the cursor, and it closes the cursor again when the loop exits. A list of actual argument value expressions must appear if and only if the cursor was declared to take arguments. These values will be substituted in the query, in just the same way as during an <command>OPEN</command> (see <xref linkend="plpgsql-open-bound-cursor"/>). カーソル変数は宣言されたとき、何らかの問い合わせと結び付けられて(バインドされて)いなければならず、また既に開かれていてはなりませんFOR文は自動的にカーソルを開き、ループから抜けたときに再度閉じます。 実際の引数値式のリストは、カーソルが引数を取ることを宣言された場合に限ってのみ出現できます。 これらの値は、OPEN過程と同じ方法で、問い合わせの中で置換されます(41.7.2.3を参照してください)。

The variable <replaceable>recordvar</replaceable> is automatically defined as type <type>record</type> and exists only inside the loop (any existing definition of the variable name is ignored within the loop). Each row returned by the cursor is successively assigned to this record variable and the loop body is executed. recordvar変数は、record型として自動的に定義され、ループ内でのみ存在します (存在するいかなる変数名の定義もループ内では無視されます)。 カーソルによって返されたそれぞれの行はこのレコード変数に引き続いて割り当てられ、ループ本体が実行されます。