DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR query [ FOR { READ ONLY | UPDATE [ OF column [, ...] ] } ]
DECLAREを使うと、巨大な問い合わせの結果から一度に少数の行を取り出す機能であるカーソルが使用できるようになります。 FETCHを使うと、カーソルからテキスト形式またはバイナリ形式でデータを取り出すことができます。
通常のカーソルは、SELECTの出力と同じテキスト形式でデータを返します。 元のデータは固有のバイナリ形式で保存されているので、システムがテキスト形式を生成するためにデータを変換する必要があります。 情報がテキスト形式で返された後、クライアントアプリケーション側で情報を処理するためにバイナリ形式に変換しなければならないことがあります。 また、テキスト形式は、対応するバイナリ形式よりサイズが大きくなりがちです。 BINARYカーソルを使うと、データをバイナリ表現のまま返すことができ、この方が操作がより簡単になる可能性があります。 それでも、データをテキストとして表示する場合は、テキスト形式でデータを取り出すことにより、クライアント側の処理を軽減できます。
例えば、問い合わせが整数の列から値として1を返す場合、デフォルトのカーソルからは1という文字列を取得することになりますが、バイナリ形式のカーソルからは、内部表現を使った4バイトの値を取得することになります(バイトオーダはビッグエンディアン)。
バイナリ形式のカーソルは注意して使わなければなりません。 psqlなどの多くのアプリケーションは、データはテキスト形式で返されるものとみなしており、バイナリ形式のカーソルを扱うことができません。
注意: クライアントアプリケーションが"拡張問い合わせ"プロトコルを使用してFETCHコマンドを発行する場合、テキスト形式とバイナリ形式のどちらでデータを受け取るのかは、バインドプロトコルメッセージで指定します。 この選択は、カーソル定義での指定を上書きします。 全てのカーソルをテキスト形式/バイナリ形式のどちらでも扱うことができる拡張問い合わせプロトコルでは、バイナリカーソルの概念はサポートされていません。
作成されるカーソルの名前です。
カーソルによるデータの取得が、テキスト形式ではなくバイナリ形式になります。
カーソルが存在する間、カーソルから取り出されたデータが背後にあるテーブルの更新の影響を受けないことを示します。 しかし、PostgreSQLでは、どのような場合であってもカーソルは更新の影響を受けません。 したがって、このキーワードを使用しても現在のところ効果はありません。このキーワードは、標準SQLとの互換性を保持するために存在しています。
SCROLLは、そのカーソルから通常の順序通りでない方法で(例えば後方から)行を取り出すことを指定します。 問い合わせの実行計画が複雑になると、SCROLLの指定によって問い合わせの実行時間が増大する可能性があります。 NO SCROLLは、そのカーソルから順序通りでない方法では行を取り出せないことを指定します。 デフォルトでは、いくつかの場合でスクロール可能です。 これはSCROLLの指定と同じではありません。 詳細は注釈を参照してください。
WITH HOLDは、カーソルを生成したトランザクションが正常にコミット処理を行った後も、そのカーソルの使用を続けられることを指定します。 WITHOUT HOLDは、カーソルを生成したトランザクションの外部では、そのカーソルを使用できないことを指定します。 WITH HOLDもWITHOUT HOLDも指定されない場合、WITHOUT HOLDがデフォルトとなります。
FOR READ ONLYは、カーソルが読み取り専用モードで使用されることを示します。 FOR UPDATEは、カーソルがテーブルを更新するために使用されることを示します。 現時点では、PostgreSQLはカーソルでの更新をサポートしていません。したがって、FOR UPDATEを指定するとエラーメッセージが表示されます。また、FOR READ ONLYを指定しても効果はありません。
カーソルによって更新される列(複数可)です。 現時点では、PostgreSQLはカーソルでの更新をサポートしていません。したがって、FOR UPDATE句を指定するとエラーメッセージが表示されます。
BINARY、INSENSITIVE、SCROLLキーワードは任意の順番で指定することができます。
WITH HOLDが指定されなければ、このコマンドで生成されるカーソルは現在のトランザクションの中でのみ使用することができます。 したがって、WITH HOLDのないDECLAREはトランザクションブロックの外側では意味がありません。 その場合、カーソルはこの文が完了するまでのみ有効です。 そのため、PostgreSQLはトランザクションブロックの外部でこのコマンドが使用された場合エラーを報告します。 トランザクションブロックを定義するには、BEGIN、COMMIT、ROLLBACKを使用してください。
WITH HOLDが指定された場合、カーソルを作成したトランザクションのコミットに成功していても、同一セッション内のその後のトランザクションからそのカーソルにアクセスすることができます (ただし、トランザクションがアボートされた場合、そのカーソルは削除されます)。 WITH HOLD付きで作成されたカーソルは、そのカーソルに対して明示的なCLOSEが発行された場合やセッションが終了した時に閉じられます。 現在の実装では、保持されたカーソルを使って表される行は、その後のトランザクションでも利用できるように、一時ファイルかメモリ領域にコピーされます。
カーソルから逆方向にデータを取り出す時には、SCROLLオプションを指定しなければなりません。 これは標準SQLでは必須となっています。 しかし、以前のバージョンとの互換性を保持するために、PostgreSQLでは、カーソルの問い合わせ計画が単純であり、そのサポートに余計なオーバーヘッドが必要ない場合、 SCROLLなしでも逆方向にデータを取り出すことができます。 しかし、SCROLLを付けなくても逆方向にデータが取り出せることを利用してアプリケーションを開発するのはお勧めしません。 NO SCROLLを指定した場合は、どのような場合でも逆方向に取り出すことはできません。
標準SQLでは、組み込みSQLにおけるカーソルのみが規定されています。 PostgreSQLサーバはカーソル用のOPEN文を実装していません。 カーソルは宣言された時に開いたものとみなされています。 しかし、PostgreSQL用の埋め込みSQLプリプロセッサであるECPGでは、DECLAREとOPEN文などを含め、標準SQLのカーソル規定をサポートしています。
pg_cursorsシステムビューを問い合わせることで、利用可能なすべてのカーソルを確認することができます。