SQL の forEach に関する考慮事項

EGL の forEach 文は 各行で EGL ステートメントを実行しながら、SQL 結果セットを読み取ります。 EGL の open 文または get 文を使用して、あらかじめ結果セットを作成しておく必要があります。 結果セットを使用できない場合、この文を処理することはできず、ハード入出力エラーが発生します。 ループは、次のイベントの 1 つが発生するまで継続します。

ほとんどの場合、EGL ランタイムは最後のループの反復後に暗黙の SQL CLOSE 文を実行します。 この暗黙のステートメントは SQL システム変数を変更するため、forEach ステートメントの本文に SQL 関連のシステム変数の値を保存する必要があります。

EGL ランタイムは、forEach 文が noRecordFound 以外のエラーのために終了した場合には、 SQL CLOSE 文を実行しません。

構文

forEach 文の構文図
label
ラベル。後にコロンが続き、continue 文または exit 文で参照できます。詳しくは、 条件およびループ文を参照してください。
sqlRecord
結果セットを作成した open 文または get 文で参照した SQL レコード変数。 SQL レコードまたは結果セット ID を指定する必要があります。
resultSetID
現在の読み取り対象である結果セットを作成した open 文または get 文に指定した任意の識別子。
target
EGL が生成する SQL の INTO 文節では、ここに指定した情報を使用します。 これらは、結果セットの各行について forEach 文が生成する SQL の FETCH 文の値を受け取る EGL ホスト変数です。 レコード名を指定すると、EGL はそのレコード内のすべてのフィールドを使用します。 ホスト変数の名前の前にコロンを挿入しないでください (ホスト変数を参照)。

このコンテキストで INTO 文節を作成すると、関連する open 文からすべての INTO 文節がオーバーライドされます。

statement
結果セットの各行について実行される、EGL 言語の文。

以下に、カスタマー・ファイル内のデータベース・レコードを変更するプロセスの例を示します。
vgVar.handleHardIOErrors  = 1;

try
  open myResults for myCustomer
    with #sql{
      SELECT customer_number, customer_name
      FROM Customer
      WHERE customer_number >= :myCustomer.customerNumber
      FOR UPDATE OF customer_name
    }
    into myCustomer.customerNumber, myCustomer.customerName;
onException(sqlEx SQLException)
  myErrorHandler(6);    // プログラムを終了する
end

try 
  forEach (from myResults)
    // 最初に姓を作成する
    reverseName(myCustomer.customerName);

    try
      execute
        #sql{
          UPDATE Customer
          SET customer_name = :myCustomer.customerName
          WHERE CURRENT OF myResults
        };
    onException(sqlEx SQLException)
      myErrorHandler(10); // プログラムを終了する
    end
  end  
  
onException(sqlEx SQLException)
  myErrorHandler(8);  // プログラムを終了する
end

sysLib.commit();

エラー条件

100 の SQLCODE は、一致するデータが見つからなかったことを示します。 このエラーでは、forEach ブロックが通常どおりに終了されます。 EGL が、こうした状況で forEach に関連する onException ブロックを実行することはありません。 次の例のようなテストで onException ブロックを開始する必要はありません。
onException(sqlEx SQLException)
  if (sqlcode != 100)  // 不要なテスト

フィードバック