DECLARE <refpurpose>define a cursor</refpurpose> — カーソルを定義する
DECLAREname
[ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FORquery
<command>DECLARE</command> allows a user to create cursors, which
can be used to retrieve
a small number of rows at a time out of a larger query.
After the cursor is created, rows are fetched from it using
<link linkend="sql-fetch"><command>FETCH</command></link>.
DECLARE
を使うと、カーソルが使用できるようになります。
これは、巨大な問い合わせの結果から一度に少数の行を取り出す機能です。
カーソルを作成した後、FETCH
を使用して行を取り出します。
This page describes usage of cursors at the SQL command level. If you are trying to use cursors inside a <application>PL/pgSQL</application> function, the rules are different — see <xref linkend="plpgsql-cursors"/>. このマニュアルページではSQLコマンドレベルでのカーソルの使用方法について説明します。 PL/pgSQL内でカーソルを使用するつもりであれば、規則が異なりますので、41.7を参照してください。
name
The name of the cursor to be created. This must be different from any other active cursor name in the session. 作成されるカーソルの名前です。 これはセッションで実行中の他のカーソルの名前とは異なるものでなければなりません。
BINARY
Causes the cursor to return data in binary rather than in text format. カーソルによるデータの取得が、テキスト形式ではなくバイナリ形式になります。
ASENSITIVE
INSENSITIVE
Cursor sensitivity determines whether changes to the data underlying the
cursor, done in the same transaction, after the cursor has been
declared, are visible in the cursor. <literal>INSENSITIVE</literal>
means they are not visible, <literal>ASENSITIVE</literal> means the
behavior is implementation-dependent. A third behavior,
<literal>SENSITIVE</literal>, meaning that such changes are visible in
the cursor, is not available in <productname>PostgreSQL</productname>.
In <productname>PostgreSQL</productname>, all cursors are insensitive;
so these key words have no effect and are only accepted for
compatibility with the SQL standard.
カーソルの感度とは、カーソルの背後にあるデータが、カーソルが宣言された後に、同じトランザクション内で変更された場合、それがそのカーソル内で可視かどうかを決めるものです。
INSENSITIVE
は可視ではないことを意味し、ASENSITIVE
は、その振舞いが実装依存であることを意味します。
第3の振舞いであるSENSITIVE
はそのような変更がカーソル内で可視であることを意味しますが、PostgreSQLでは利用できません。
PostgreSQLでは、カーソルはすべてinsensitiveですので、このキーワードを使用しても効果はなく、このキーワードは標準SQLとの互換性を保持するために存在しています。
Specifying <literal>INSENSITIVE</literal> together with <literal>FOR
UPDATE</literal> or <literal>FOR SHARE</literal> is an error.
INSENSITIVE
をFOR UPDATE
またはFOR SHARE
といっしょに指定するとエラーになります。
SCROLL
NO SCROLL
SCROLL
は、そのカーソルから通常の順序通りでない方法で(例えば後方から)行を取り出し可能であることを指定します。
問い合わせの実行計画が複雑になると、SCROLL
の指定によって問い合わせの実行時間が増大する可能性があります。
NO SCROLL
は、そのカーソルから順序通りでない方法では行を取り出せないことを指定します。
デフォルトでは、いくつかの場合でスクロール可能です。
これはSCROLL
の指定と同じではありません。
詳細は注釈を参照してください。
WITH HOLD
WITHOUT HOLD
WITH HOLD
は、カーソルを生成したトランザクションが正常にコミット処理を行った後も、そのカーソルの使用を続けられることを指定します。
WITHOUT HOLD
は、カーソルを生成したトランザクションの外部では、そのカーソルを使用できないことを指定します。
WITH HOLD
もWITHOUT HOLD
も指定されない場合、WITHOUT HOLD
がデフォルトとなります。
query
A <link linkend="sql-select"><command>SELECT</command></link> or
<link linkend="sql-values"><command>VALUES</command></link> command
which will provide the rows to be returned by the cursor.
カーソルによって返される行を提供するSELECT
またはVALUES
コマンドです。
The key words <literal>ASENSITIVE</literal>, <literal>BINARY</literal>,
<literal>INSENSITIVE</literal>, and <literal>SCROLL</literal> can
appear in any order.
ASENSITIVE
、BINARY
、INSENSITIVE
、SCROLL
キーワードは任意の順番で指定することができます。
Normal cursors return data in text format, the same as a
<command>SELECT</command> would produce. The <literal>BINARY</literal> option
specifies that the cursor should return data in binary format.
This reduces conversion effort for both the server and client,
at the cost of more programmer effort to deal with platform-dependent
binary data formats.
As an example, if a query returns a value of one from an integer column,
you would get a string of <literal>1</literal> with a default cursor,
whereas with a binary cursor you would get
a 4-byte field containing the internal representation of the value
(in big-endian byte order).
通常のカーソルは、SELECT
の出力と同じテキスト形式でデータを返します。
BINARY
は、カーソルがバイナリ形式でデータを返すことを示します。
これによりサーバ、クライアントの両方で変換に関する作業を省くことができますが、プラットフォームに依存するバイナリデータ書式を扱うためのプログラマの作業が大きくなります。
例えば、問い合わせが整数の列から値として1を返す場合、デフォルトのカーソルからは1
という文字列を取得することになりますが、バイナリ形式のカーソルからは、内部表現を使った4バイトの値を(ビッグエンディアンのバイト順で)取得することになります。
Binary cursors should be used carefully. Many applications, including <application>psql</application>, are not prepared to handle binary cursors and expect data to come back in the text format. バイナリ形式のカーソルは注意して使わなければなりません。 psqlなどの多くのアプリケーションは、データはテキスト形式で返されることを期待しており、バイナリ形式のカーソルを扱うことができません。
When the client application uses the <quote>extended query</quote> protocol
to issue a <command>FETCH</command> command, the Bind protocol message
specifies whether data is to be retrieved in text or binary format.
This choice overrides the way that the cursor is defined. The concept
of a binary cursor as such is thus obsolete when using extended query
protocol — any cursor can be treated as either text or binary.
クライアントアプリケーションが「拡張問い合わせ」プロトコルを使用してFETCH
コマンドを発行する場合、テキスト形式とバイナリ形式のどちらでデータを受け取るのかは、バインドプロトコルメッセージで指定します。
この選択は、カーソル定義での指定を上書きします。
全てのカーソルをテキスト形式/バイナリ形式のどちらでも扱うことができる拡張問い合わせプロトコルでは、バイナリカーソルという概念は旧式なものです。
Unless <literal>WITH HOLD</literal> is specified, the cursor
created by this command can only be used within the current
transaction. Thus, <command>DECLARE</command> without <literal>WITH
HOLD</literal> is useless outside a transaction block: the cursor would
survive only to the completion of the statement. Therefore
<productname>PostgreSQL</productname> reports an error if such a
command is used outside a transaction block.
Use
<link linkend="sql-begin"><command>BEGIN</command></link> and
<link linkend="sql-commit"><command>COMMIT</command></link>
(or <link linkend="sql-rollback"><command>ROLLBACK</command></link>)
to define a transaction block.
WITH HOLD
が指定されなければ、このコマンドで生成されるカーソルは現在のトランザクションの中でのみ使用することができます。
したがって、WITH HOLD
のないDECLARE
はトランザクションブロックの外側では意味がありません。
その場合、カーソルはこの文が完了するまでのみ有効です。
そのため、PostgreSQLはトランザクションブロックの外部でこうしたコマンドが使用された場合エラーを報告します。
トランザクションブロックを定義するには、BEGIN
とCOMMIT
(またはROLLBACK
)を使用してください。
If <literal>WITH HOLD</literal> is specified and the transaction
that created the cursor successfully commits, the cursor can
continue to be accessed by subsequent transactions in the same
session. (But if the creating transaction is aborted, the cursor
is removed.) A cursor created with <literal>WITH HOLD</literal>
is closed when an explicit <command>CLOSE</command> command is
issued on it, or the session ends. In the current implementation,
the rows represented by a held cursor are copied into a temporary
file or memory area so that they remain available for subsequent
transactions.
WITH HOLD
が指定され、カーソルを作成したトランザクションのコミットに成功した場合、同一セッション内のその後のトランザクションからそのカーソルにアクセスすることができます
(ただし、トランザクションがアボートされた場合、そのカーソルは削除されます)。
WITH HOLD
付きで作成されたカーソルは、そのカーソルに対して明示的なCLOSE
が発行された場合やセッションが終了した時に閉じられます。
現在の実装では、保持されたカーソルを使って表される行は、その後のトランザクションでも利用できるように、一時ファイルかメモリ領域にコピーされます。
<literal>WITH HOLD</literal> may not be specified when the query
includes <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>.
問い合わせがFOR UPDATE
またはFOR SHARE
を含む場合、WITH HOLD
を指定することはできません。
The <literal>SCROLL</literal> option should be specified when defining a
cursor that will be used to fetch backwards. This is required by
the SQL standard. However, for compatibility with earlier
versions, <productname>PostgreSQL</productname> will allow
backward fetches without <literal>SCROLL</literal>, if the cursor's query
plan is simple enough that no extra overhead is needed to support
it. However, application developers are advised not to rely on
using backward fetches from a cursor that has not been created
with <literal>SCROLL</literal>. If <literal>NO SCROLL</literal> is
specified, then backward fetches are disallowed in any case.
カーソルから逆方向にデータを取り出す時には、SCROLL
オプションを指定するべきです。
これは標準SQLでは必須となっています。
しかし、以前のバージョンとの互換性を保持するために、PostgreSQLでは、カーソルの問い合わせ計画が単純であり、そのサポートに余計なオーバーヘッドが必要ない場合、 SCROLL
なしでも逆方向にデータを取り出すことができます。
しかし、SCROLL
を付けなくても逆方向にデータが取り出せることを利用してアプリケーションを開発するのはお勧めしません。
NO SCROLL
を指定した場合は、どのような場合でも逆方向に取り出すことはできません。
Backward fetches are also disallowed when the query
includes <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>; therefore
<literal>SCROLL</literal> may not be specified in this case.
また、問い合わせがFOR UPDATE
またはFOR SHARE
を含む場合は、逆方向の取り出しは許されません。
このためこの場合はSCROLL
を指定することはできません。
Scrollable cursors may give unexpected
results if they invoke any volatile functions (see <xref
linkend="xfunc-volatility"/>). When a previously fetched row is
re-fetched, the functions might be re-executed, perhaps leading to
results different from the first time. It's best to
specify <literal>NO SCROLL</literal> for a query involving volatile
functions. If that is not practical, one workaround
is to declare the cursor <literal>SCROLL WITH HOLD</literal> and commit the
transaction before reading any rows from it. This will force the
entire output of the cursor to be materialized in temporary storage,
so that volatile functions are executed exactly once for each row.
スクロール可能なカーソルが揮発関数(36.7参照)を含む場合、想定しない結果をもたらす可能性があります。
これまで取り出した行を再度取り出した時、関数は再実行される可能性があり、この場合おそらく初回と異なる結果をもたらします。
揮発関数を含む問い合わせに対してはNO SCROLL
を指定するのが最善です。
それが現実的でないのなら、回避方法の1つは、カーソルをWITH HOLD
と宣言し、そこから何か行を読み取る前にトランザクションをコミットすることです。
これにより強制的にカーソルの出力全体が一時領域に具現化され、揮発関数は各行に対して厳密に1度だけ実行されます。
If the cursor's query includes <literal>FOR UPDATE</literal> or <literal>FOR
SHARE</literal>, then returned rows are locked at the time they are first
fetched, in the same way as for a regular
<link linkend="sql-select"><command>SELECT</command></link> command with
these options.
In addition, the returned rows will be the most up-to-date versions.
カーソルの問い合わせがFOR UPDATE
またはFOR SHARE
を含む場合、このオプションを持つ通常のSELECT
コマンドと同様、返される行は取り出した時点でロックされます。
さらに、返される行はもっとも最新のバージョンになります。
It is generally recommended to use <literal>FOR UPDATE</literal> if the cursor
is intended to be used with <command>UPDATE ... WHERE CURRENT OF</command> or
<command>DELETE ... WHERE CURRENT OF</command>. Using <literal>FOR UPDATE</literal>
prevents other sessions from changing the rows between the time they are
fetched and the time they are updated. Without <literal>FOR UPDATE</literal>,
a subsequent <literal>WHERE CURRENT OF</literal> command will have no effect if
the row was changed since the cursor was created.
カーソルをUPDATE ... WHERE CURRENT OF
またはDELETE ... WHERE CURRENT OF
で使用するつもりならば、FOR UPDATE
の使用を通常勧めます。
FOR UPDATE
を使用することで、取り出してから更新されるまでの間に他のセッションが行を変更することを防止します。
FOR UPDATE
がなければ、カーソル作成後に行が変更された場合に後に行うWHERE CURRENT OF
コマンドは効果がなくなります。
Another reason to use <literal>FOR UPDATE</literal> is that without it, a
subsequent <literal>WHERE CURRENT OF</literal> might fail if the cursor query
does not meet the SQL standard's rules for being <quote>simply
updatable</quote> (in particular, the cursor must reference just one table
and not use grouping or <literal>ORDER BY</literal>). Cursors
that are not simply updatable might work, or might not, depending on plan
choice details; so in the worst case, an application might work in testing
and then fail in production. If <literal>FOR UPDATE</literal> is
specified, the cursor is guaranteed to be updatable.
FOR UPDATE
を使用する他の理由は、「簡単に更新可能」にするためにカーソル問い合わせが標準SQLに合わない場合(具体的にはカーソルは1つのテーブルのみを参照しなければならず、また、グループ化やORDER BY
を使用してはならない)、これがないと後に実行されるWHERE CURRENT OF
が失敗するかもしれないことです。
計画選択の詳細によっては、簡単に更新可能でないカーソルは動作するかもしれませんし、動作しないかもしれません。
このため最悪の場合、アプリケーションは試験時に動作するが、運用時に失敗するかもしれません。
FOR UPDATE
が指定されていれば、カーソルは更新可能であることが保証されています。
The main reason not to use <literal>FOR UPDATE</literal> with <literal>WHERE
CURRENT OF</literal> is if you need the cursor to be scrollable, or to be
isolated from concurrent updates (that is, continue to show the old
data). If this is a requirement, pay close heed to the caveats shown
above.
FOR UPDATE
をWHERE CURRENT OF
といっしょに使用しない大きな理由は、カーソルをスクロール可能にする必要がある、または同時並行の更新から隔離する(つまり古いデータを表示し続けるようにする)必要がある場合のためです。
これが必要ならば、上記の警告に十分注意してください。
The SQL standard only makes provisions for cursors in embedded
<acronym>SQL</acronym>. The <productname>PostgreSQL</productname>
server does not implement an <command>OPEN</command> statement for
cursors; a cursor is considered to be open when it is declared.
However, <application>ECPG</application>, the embedded SQL
preprocessor for <productname>PostgreSQL</productname>, supports
the standard SQL cursor conventions, including those involving
<command>DECLARE</command> and <command>OPEN</command> statements.
標準SQLでは、組み込みSQLにおけるカーソルのみが規定されています。
PostgreSQLサーバはカーソル用のOPEN
文を実装していません。
カーソルは宣言された時に開いたものとみなされています。
しかし、PostgreSQL用の埋め込みSQLプリプロセッサであるECPGでは、DECLARE
とOPEN
文などを含め、標準SQLのカーソル規定をサポートしています。
The server data structure underlying an open cursor is called a
<firstterm>portal</firstterm>. Portal names are exposed in the
client protocol: a client can fetch rows directly from an open
portal, if it knows the portal name. When creating a cursor with
<command>DECLARE</command>, the portal name is the same as the
cursor name.
開いたカーソルの基礎となるサーバデータ構造はポータルと呼ばれます。
ポータル名はクライアントプロトコルで公開されます。クライアントは、ポータル名を知っていれば、開いたポータルから直接行を取り出すことができます。
DECLARE
を使用してカーソルを作成する場合、ポータル名はカーソル名と同じです。
You can see all available cursors by querying the <link
linkend="view-pg-cursors"><structname>pg_cursors</structname></link>
system view.
pg_cursors
システムビューを問い合わせることで、利用可能なすべてのカーソルを確認することができます。
To declare a cursor: カーソルを宣言します。
DECLARE liahona CURSOR FOR SELECT * FROM films;
See <xref linkend="sql-fetch"/> for more examples of cursor usage. カーソル使用の他の例についてはFETCHを参照してください。
The SQL standard allows cursors only in embedded <acronym>SQL</acronym> and in modules. <productname>PostgreSQL</productname> permits cursors to be used interactively. 標準SQLでは、カーソルを埋め込みSQL内とモジュール内でのみ使用できます。 PostgreSQLでは、対話式にカーソルを使うことができます。
According to the SQL standard, changes made to insensitive cursors by
<literal>UPDATE ... WHERE CURRENT OF</literal> and <literal>DELETE
... WHERE CURRENT OF</literal> statements are visible in that same
cursor. <productname>PostgreSQL</productname> treats these statements like
all other data changing statements in that they are not visible in
insensitive cursors.
標準SQLに従えば、UPDATE ... WHERE CURRENT OF
とDELETE ... WHERE CURRENT OF
文によりinsensitiveカーソルで行なわれた変更は、同じカーソルでは可視です。
PostgreSQLは、これらの文をその他のデータを変更する文すべてと同様に扱い、insensitiveカーソルでは変更は可視ではありません。
Binary cursors are a <productname>PostgreSQL</productname> extension. バイナリカーソルはPostgreSQLの拡張です。