DECLARE(7)

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

SYNOPSIS

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

説明

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

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

パラメータ

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

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

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

SCROLL

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

WITH HOLD

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

query
    カーソルによって返される行を提供するSELECT [select(7)]またはVALUES [values(7)]コマンドです。

BINARY、INSENSITIVE、SCROLLキーワードは任意の順番で指定することができます。

注釈

通常のカーソルは、SELECTの出力と同じテキスト形式でデータを返します。 BINARYは、カーソルがバイナリ形式でデータを返さなければならないことを示します。 これによりサーバ、クライアントの両方で変換に関する作業を省くことができますが、プラットフォームに依存するバイナリデータ書式を扱うためのプログラマの作業が大きくなります。 例えば、問い合わせが整数の列から値として1を返す場合、デフォルトのカーソルからは1という文字列を取得することになりますが、バイナリ形式のカーソルからは、内部表現を使った4バイトの値を取得することになります（バイトオーダはビッグエンディアン）。

バイナリ形式のカーソルは注意して使わなければなりません。 psqlなどの多くのアプリケーションは、データはテキスト形式で返されるものとみなしており、バイナリ形式のカーソルを扱うことができません。

    Note: クライアントアプリケーションが``拡張問い合わせ''プロトコルを使用してFETCHコマンドを発行する場合、テキスト形式とバイナリ形式のどちらでデータを受け取るのかは、バインドプロトコルメッセージで指定します。 この選択は、カーソル定義での指定を上書きします。 全てのカーソルをテキスト形式/バイナリ形式のどちらでも扱うことができる拡張問い合わせプロトコルでは、バイナリカーソルという概念は旧式なものです。

WITH HOLDが指定されなければ、このコマンドで生成されるカーソルは現在のトランザクションの中でのみ使用することができます。 したがって、WITH HOLDのないDECLAREはトランザクションブロックの外側では意味がありません。 その場合、カーソルはこの文が完了するまでのみ有効です。 そのため、PostgreSQLはトランザクションブロックの外部でこうしたコマンドが使用された場合エラーを報告します。 トランザクションブロックを定義するには、BEGIN [begin(7)]とCOMMIT [commit(7)]（またはROLLBACK [rollback(7)]）を使用してください。

WITH HOLDが指定された場合、カーソルを作成したトランザクションのコミットに成功していても、同一セッション内のその後のトランザクションからそのカーソルにアクセスすることができます （ただし、トランザクションがアボートされた場合、そのカーソルは削除されます）。 WITH HOLD付きで作成されたカーソルは、そのカーソルに対して明示的なCLOSEが発行された場合やセッションが終了した時に閉じられます。 現在の実装では、保持されたカーソルを使って表される行は、その後のトランザクションでも利用できるように、一時ファイルかメモリ領域にコピーされます。

問い合わせがFOR UPDATEまたはFOR SHAREを含む場合、WITH HOLDを指定することはできません。

カーソルから逆方向にデータを取り出す時には、SCROLLオプションを指定しなければなりません。 これは標準SQLでは必須となっています。 しかし、以前のバージョンとの互換性を保持するために、PostgreSQLでは、カーソルの問い合わせ計画が単純であり、そのサポートに余計なオーバーヘッドが必要ない場合、 SCROLLなしでも逆方向にデータを取り出すことができます。 しかし、SCROLLを付けなくても逆方向にデータが取り出せることを利用してアプリケーションを開発するのはお勧めしません。 NO SCROLLを指定した場合は、どのような場合でも逆方向に取り出すことはできません。

また、問い合わせがFOR UPDATEまたはFOR SHAREを含む場合は、逆方向の取り出しは許されません。 このためこの場合はSCROLLを指定することはできません。

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

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

    Caution:

    カーソルを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 [fetch(7)]を参照してください。

互換性

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

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

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

関連項目
CLOSE [close(7)], FETCH [fetch(7)], MOVE [move(7)]