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