LOOP;下限が上限よりも大きい(REVERSEの場合はより小さい)場合、ループ本体はまったく実行されません。エラーは発生しません。labelをFORループに付加することにより、labelを用いて修飾した名前の整数ループ変数を参照できます。問い合わせ結果による繰り返し別の種類のFORループを使用して、問い合わせの結果を繰り返し、そのデータを扱うことができます。以下に構文を示します。];targetは、レコード変数、行変数またはカンマで区切ったスカラ変数のリストです。targetには順次、queryの結果の全ての行が代入され、各行に対してループ本体が実行されます。plpgsql;このループがEXIT文で終了した場合、最後に割り当てられた行の値はループを抜けた後でもアクセスすることができます。この種類のFOR文のqueryとしては、呼び出し元に行を返すSQLコマンドをすべて使用できます。通常はSELECTですが、RETURNING句を持つINSERT、UPDATEまたはDELETEも使用できます。EXPLAINなどのユーティリティコマンドも作動します。PL/pgSQL変数は問い合わせテキストに置き換えられます。問い合わせ計画は、項39.10.1および項39.10.2で述べたように、再利用のためにキャッシュされます。FOR-IN-EXECUTE文は行を繰り返すもう1つの方法です。];この方法は、問い合わせのソースが文字列式で指定される点を除き、前の形式と似ています。この式はFORループの各項目で評価され、再計画が行われます。これにより、プログラマは、通常のEXECUTE文と同じように事前に計画された問い合わせによる高速性と、動的な問い合わせの持つ柔軟性を選択することができます。EXECUTEの場合と同様、パラメータ値はUSINGにより動的コマンドに挿入できます。結果を通して繰り返さなければならない問い合わせを指定するもう1つの方法として、カーソルの宣言があります。これは項39.7.4で説明します。配列を巡回FOREACHループはFORループにとてもよく似ています。問い合わせが抽出した行を繰り返す代わりに、配列の要素を繰り返します。(一般的にFOREACHは、複合値で表現される構成要素の巡回を意味しますが、配列でない複合値も巡回する亜種が将来は追加されるかもしれません。配列を巡回するFOREACH文を示します。0が指定された場合、ループはexpressionによって評価されて作成された配列の各要素を繰り返します。target変数が各要素の値に順次割り当てられ、各要素に対してループ本体が実行されます。整数配列の要素を巡回する例を示します。plpgsql;配列の次元数に関係なく、要素は格納した順番で処理されます。通常targetは単一の変数ですが、複合値(レコード)の配列を巡回するときは、変数のリストも可能です。その場合、配列の各要素に対して、変数は複合値(レコード)の列から連続的に割り当てられます。正のSLICE値を持つ場合、FOREACHは単一の要素ではなく多次元配列の低次元部分配列を通して繰り返します。SLICE値は、配列の次元数より小さい整数定数でなければなりません。target変数は配列でなければなりません。ここで部分配列はSLICEで指定した次数となります。以下に1次元の部分配列を通した繰り返しの例を示します。エラーの捕捉デフォルトでは、PL/pgSQL関数の内部で発生したエラーは関数の実行を中止し、実際に上位のトランザクションをアボートします。BEGINブロックおよびEXCEPTION句を使用すれば、エラーを捕捉してその状態から回復できます。その構文は通常のBEGINブロックの構文を拡張したものです。]END;エラーが発生しない時、この形式のブロックは単に全てのstatementsを実行し、ENDの次の文に制御が移ります。statementsの内部でエラーが発生すると、それ以後のstatementsの処理は中断され、EXCEPTIONリストに制御が移ります。リストの中から、発生したエラーと合致する最初のconditionを探します。合致するものがあれば、対応するhandler_statementsを実行し、ENDの次の文に制御が移ります。合致するものがなければ、EXCEPTION句が存在しないのと同じで、エラーは外側に伝播します。EXCEPTIONを含んだ外側のブロックはエラーを捕捉できますが、失敗すると関数の処理は中断されます。全てのconditionの名前は付録Aに示したもののいずれかを取ることができます。分類名はそこに分類される全てのエラーに合致します。OTHERSという特別の状態名はQUERY_CANCELED以外の全てのエラーに合致します。(QUERY_CANCELEDを名前で捕捉することは可能ですが、賢明ではありません。状態名は大文字小文字を区別しません。同時に、エラー状態はSQLSTATEコードで指定可能です。...エラーが該当するhandler_statements内部で新たに発生した時、EXCEPTION句はそのエラーを捕捉できずエラーは外側に伝播します。上位のEXCEPTION句はそのエラーを捕捉できます。EXCEPTION句がエラーを捕捉した時、PL/pgSQL関数のローカル変数はエラーが起こった後の状態を保ちます。ブロック内部における永続的なデータベースの状態は、ロールバックされます。そのような例を以下に示します。x;END;制御が変数yの代入に移ると、division_by_zeroエラーとなり、EXCEPTION句がそのエラーを捕捉します。RETURN文による関数の戻り値は、1を加算した後のxの値となりますが、UPDATEコマンドによる結果はロールバックされます。前のブロックのINSERTコマンドはロールバックされません。Jonesではありません。EXCEPTION句を含んだブロックの実行に要する時間は、含まないブロックに比べてとても長くなります。したがって、必要のない時にEXCEPTIONを使用してはいけません。UPDATE/INSERTの例外これはUPDATEまたはINSERTの実行における例外処理を使用した適当な例題です。'dennis');このコーディングではunique_violationエラーの原因がINSERTによるものであり、テーブルのトリガ関数内部のINSERTによるものでないと仮定します。テーブルに2つ以上の一意インデックスが存在した場合、どちらのインデックスがエラーの原因になろうと操作を再試行するので、誤作動となります。捕捉したエラーが予測したものであるか検証するために、次節で記述するエラー情報を利用すれば、より安全となります。例外ハンドラはしばしば、起こった特定のエラーを識別する必要があります。現在の例外に関する情報を取得する方法は2つあります。DIAGNOSTICSコマンドです。例外ハンドラの内部では、特殊な変数SQLSTATE変数が起こった例外に対応したエラーコード(表A-1のエラーコード表を参照してください)を保有します。特殊な変数SQLERRMは例外に関連したエラーメッセージを保有します。これらの変数は、例外ハンドラの外部では定義されていません。DIAGNOSTICSコマンドを使用して、現在の例外に関する情報を取り出すこともできます。次のようなやり方となります。各itemは、指定された変数(これは受け取るために正しいデータ型でなければなりません)に代入される状態値を識別するキーワードです。現在使用可能なステータス項目は表39-1に表示されています。例外が項目の値を設定しない場合、空文字列が返されます。