SQL の replace に関する考慮事項

SQL のコンテキストでは、EGL replace 文は、SQL レコード変数からリレーショナル・データベースの行に、改訂された情報を戻します。

この文は、生成済みコードにおいて、SQL UPDATE 文を作成します。 EGL では、SQL レコード変数内の情報やプロパティーに基づいてこの文を暗黙的に作成できます。 また、#sql ディレクティブ (sql ディレクティブを参照) を使用して、replace 文に SQL コードを明示的に組み込むことができます。

replace 文を使用する前に、後続の置換のために行を取り出す必要があります。 これは次の 2 つの方法のいずれかで実行できます。

構文

replace 文の構文図
SQLRecordVariable
更新済み情報を配置したストレージ域を参照します。EGL はこの情報を使用して、単一データベース行を更新します。
SQLDynamicArray
この変数は、SQL レコード変数によって構成される動的配列に名前を付けます。 EGL replace は、DymicArray 全体を更新します。replace ステートメントでは with #sql{ExplicitCode} を使用する必要があります。カーソル位置は、open または get position ステートメントを使用して設定されている必要があります。
SQLDynamicArrayElement
動的配列の要素を指定できます。EGL replace は、動的配列内の指定された行を更新します。 カーソル位置は、open または get position ステートメントを使用して設定されている必要があります。
sqlStatement
EGL が他の方法で生成する暗黙の SQL UPDATE 文を置換する、組み込み SQL UPDATE 文。 #sql と左中括弧の間にスペースを入れないでください。
replaceOptions
EGL で暗黙 SQL コードを生成する場合は、その出力の形状を指定するために、以下のようなオプションがあります。
cursor
このオプションは、EGL に WHERE CURRENT OF cursorID 文節を作成するよう通知します。 これを機能させるには、get 文または open 文を使用して結果セットを作成しておく必要があります。EGL ではこれらの文が作成するカーソルに直接アクセスできないためです。 EGL は、SQL レコード変数名を使用してこの cursorID を見つけます。 このオプションはデフォルトです。
nocursor
このオプションは標準的な WHERE 文節を生成します。 keyItems プロパティーを含む明示的な SQL ステートメントまたはレコードも指定する必要があります。検証では、 nocursorusingKeys を同じステートメントに指定することは許可されていません。
usingKeys
ここで、SQLRecordVariable からのフィールド名を指定して、そのレコード定義で指定したキー・フィールドをオーバーライドできます。 このオプションは、上記のフィールドを指定して、SQL WHERE 文節の条件を提供します。 これらのフィールドは、置換対象のデータベース行の対応する列と一致する必要があります。 キー項目が、SET 文節で更新された列のリストから除外されることに注意してください。
注: 複数行操作の場合、EGL は usingKeys をサポートしません。
from resultSetID
次の各条件が true である場合は、前の EGL get 文または open 文から結果セット ID を指定する必要があります。
  • 組み込み SQL 文 (#sql ディレクティブを使用して) を使用して、結果セットを作成した。
  • コードが、EGL が生成した暗黙の SQL の列セットとは異なる、更新用列セットを取り出した。
つまり、EGL が通常この SQL レコード変数用に作成するデフォルトの結果セットをユーザーが処理していない場合は、結果セット ID を指定します。

暗黙的な SQL 文

デフォルトでは、SQL レコードを書き込む replace 文の結果は、以下のとおりです。
  • レコード・パーツ宣言におけるレコード・フィールドと SQL テーブル列の関連付けの結果、 生成されたコードが、各フィールドからのデータを、関連する SQL テーブルの列にコピーします。
  • フィールドをキー項目または読み取り専用として定義した場合、そのフィールドに対応する列内の値は影響を受けません。
SQL 文の特性は、デフォルトでは以下のとおりです。
  • 暗黙の SQL UPDATE 文には、キー項目または読み取り専用として定義されたフィールドは含まれません。
  • 特定のレコードの暗黙の SQL UPDATE 文は、以下のようになります。
    UPDATE tableName
    SET    column01 = :myField01,
           column02 = :myField02,
            ...
           columnNN = :myFieldNN    
    WHERE CURRENT OF cursor

以下は、replace ステートメントを含んだコードです。 このコードは、完全な SQL プログラム (サンプル EGL SQL プログラムに記載) から引用したものです。

  try
    get dept forupdate;
    dept.description = "Test Engineers";
    replace dept;
    commit();
  onException(sqlEx SQLException)
    sqlFailure();     
  end 

次の例は、複数行に対する replace ステートメントを示しています。

employees Employee[0]{rowsetsize=10};
Open resultset1 forUpdate with #sql{ 
    select eID, uName, PASSWORD, fName, lName, office, sex, EMail
    from EMPLOYEETEST
} for employees;
Get Next employees;

//this updates the second row in the row set with current contents
employees[2].uName = “test”;
Replace employees[2]; 

// this updates the second row in the row set with explicit variable
newName CHAR(20) = “test1”;
Replace employees[2]
         #with SQL{ update EMPLOYEETEST 
                    set uName = :newName }; 

// the index can be a variable
i int = 2;
Replace employees[i]; 

//this updates all rows in the row set with uName = "test"
//Explicit SQL must be used, otherwise there should be a 
//validation error. 
uName CHAR(10) = “test”;
Replace employees 
        #with SQL{ update EMPLOYEETEST  
                   set uName = :uName };

エラー条件

replace 文を使用した場合、無効となる主な条件には以下があります。
  • #sql ディレクティブを使用して UPDATE 型以外の型の SQL 文を組み込む。
  • 組み込みコードに SQL UPDATE 文の全部ではなく一部の文節を指定する。
  • デフォルト結果セットで作業していないとき、結果セット ID を指定しない。詳しくは、このトピックの『構文』を参照してください。
  • 次のいずれかの特性を備えた組み込み (受け入れまたは暗黙の) UPDATE 文を指定する。
    • 複数のテーブルを更新する。
    • 存在しない列、または関連するホスト変数との互換性がない列に、関連付けられている。
  • すべてのフィールドが読み取り専用である SQL レコード変数を指定する。

互換性

表 1. replace の互換性に関する考慮事項
プラットフォーム 問題
COBOL 生成 COBOL のパフォーマンスを最適にするために、replace ステートメントには常に from resultSet 文節を組み込んでください。
SQL Server 複数行の delete lastget last を同時に使用することはできません。両方のステートメントを一度に実行すると、結果セットは閉じられます。
DB2® for i5/OS™ ジャーナル処理を使用可能にするか、接続ストリングに transation isolation=none を追加する必要があります。

フィードバック