PostgreSQL 9.0.0文書
前のページ | 巻戻し |  | 早送り | 次のページ

# DECLARE

## 名前

DECLARE -- カーソルを定義する

## 概要

    DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]
        CURSOR [ { WITH | WITHOUT } HOLD ] FOR query

## 説明

`DECLARE`を使うと、巨大な問い合わせの結果から一度に少数の行を取り出す機能であるカーソルが使用できるようになります。 カーソルを作成した後、FETCHを使用して行を取り出します。

> 注意: このマニュアルページではSQLコマンドレベルでのカーソルの使用方法について説明します。 PL/pgSQL内でカーソルを使用するつもりであれば、規則が異なりますので、項39.7を参照してください。

## パラメータ

`name`

  作成されるカーソルの名前です。

`BINARY`

  カーソルによるデータの取得が、テキスト形式ではなくバイナリ形式になります。

`INSENSITIVE`

  カーソルから取り出されたデータが、カーソルを作成した後に行われた背後にあるテーブルの更新の影響を受けないことを示します。 しかし、これはPostgreSQLのデフォルトの動作です。 したがって、このキーワードを使用しても効果はなく、このキーワードは標準SQLとの互換性を保持するために存在しています。

`SCROLL`
`NO SCROLL`

  `SCROLL`は、そのカーソルから通常の順序通りでない方法で（例えば後方から）行を取り出可能であることを指定します。 問い合わせの実行計画が複雑になると、`SCROLL`の指定によって問い合わせの実行時間が増大する可能性があります。 `NO SCROLL`は、そのカーソルから順序通りでない方法では行を取り出せないことを指定します。 デフォルトでは、いくつかの場合でスクロール可能です。 これは`SCROLL`の指定と同じではありません。 詳細は注釈を参照してください。

`WITH HOLD`
`WITHOUT HOLD`

  `WITH HOLD`は、カーソルを生成したトランザクションが正常にコミット処理を行った後も、そのカーソルの使用を続けられることを指定します。 `WITHOUT HOLD`は、カーソルを生成したトランザクションの外部では、そのカーソルを使用できないことを指定します。 `WITH HOLD`も`WITHOUT HOLD`も指定されない場合、`WITHOUT HOLD`がデフォルトとなります。

`query`

  カーソルによって返される行を提供するSELECTまたはVALUESコマンドです。

`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`を含む場合は、逆方向の取り出しは許されません。 このためこの場合は`SCROLL`を指定することはできません。

注意
スクロール可能な`WITH HOLD`カーソルが揮発関数（項35.6参照）を含む場合、想定しない結果をもたらす可能性があります。 これまで取り出した行を再度取り出した時、関数は再実行される可能性があり、この場合おそらく初回と異なる結果をもたらします。 こうした問題の回避方法の1つとして、カーソルを`WITH HOLD`と宣言し、そこから何か行を読み取る前にトランザクションをコミットすることがあります。 これにより強制的にカーソルの出力全体が一時領域に具現化され、揮発関数は各行に対して1度しか実行されなくなります。

問い合わせが`FOR UPDATE`または`FOR SHARE`を含む場合、通常のこのオプションを持つSELECTコマンドと同様、返される行は取り出した時点でロックされます。 さらに、返される行はもっとも最新のバージョンになります。 したがって、このオプションは、標準SQLで"センシティブカーソル"と呼ばれるものと同じ機能を提供します。 （`INSENSITIVE`を`FOR UPDATE`または`FOR SHARE`といっしょに指定するとエラーになります。）

注意
カーソルを`UPDATE ... WHERE CURRENT OF`または`DELETE ... WHERE CURRENT OF`で使用するつもりならば、`FOR UPDATE`の使用を通常勧めます。 `FOR UPDATE`を使用することで、取り出し中および更新中に他のセッションが行を変更することを防止します。 `FOR UPDATE`がなければ、カーソル作成後に行が変更された場合に後に行う`WHERE CURRENT OF`コマンドは効果がなくなります。 `FOR UPDATE`を使用する他の理由は、"簡単に更新可能"にするためにカーソル問い合わせが標準SQLに合わない場合（具体的にはカーソルは1つのテーブルのみを参照しなければならず、また、グループ化や`ORDER BY`を使用してはならない）、これがないと後に実行される`WHERE CURRENT OF`が失敗するかもしれないことです。 計画選択の詳細によっては、簡単に更新可能でないカーソルは動作するかもしれませんし、動作しないかもしれません。 このため最悪の場合、アプリケーションは試験時に動作するが、運用時に失敗するかもしれません。 `FOR UPDATE`を`WHERE CURRENT OF`といっしょに使用しない大きな理由は、カーソルをスクロール可能にする必要がある、または後の更新の影響を受けないようにする（つまり古いデータを表示し続けるようにする）必要がある場合のためです。 これが必要ならば、上記の警告に十分注意してください。

標準SQLでは、組み込みSQLにおけるカーソルのみが規定されています。 PostgreSQLサーバはカーソル用の`OPEN`文を実装していません。 カーソルは宣言された時に開いたものとみなされています。 しかし、PostgreSQL用の埋め込みSQLプリプロセッサであるECPGでは、`DECLARE`と`OPEN`文などを含め、標準SQLのカーソル規定をサポートしています。

`pg_cursors`システムビューを問い合わせることで、利用可能なすべてのカーソルを確認することができます。

## 例

カーソルを宣言します。

    DECLARE liahona CURSOR FOR SELECT * FROM films;

カーソル使用のより多くの例についてはFETCHを参照してください。

## 互換性

標準SQLでは、デフォルトでカーソルが背後にあるデータの同時実行更新を気づかなければならないかどうかは実装依存であると述べています。 PostgreSQLのカーソルはデフォルトでは気づかず、`FOR UPDATE`を指定することで気づくことができます。 他の製品では異なる動作をするかもしれません。

標準SQLでは、カーソルを埋め込みSQL内とモジュール内でのみ使用できます。 PostgreSQLでは、対話式にカーソルを使うことができます。

バイナリカーソルはPostgreSQLの拡張です。

## 関連項目

CLOSE, FETCH, MOVE

前のページ | ホーム | 次のページ
DEALLOCATE | 上に戻る | DELETE