SQL の prepare に関する考慮事項

EGL prepare ステートメントは SQL PREPARE ステートメントを生成します。 オプションで、実行時にのみ認識される詳細を含めることもできます。 EGL の execute ステートメント、あるいは (SQL コードが結果セットを戻す場合には) EGL の open ステートメントまたは get ステートメントで、準備済み SQL コードを実行します。

構文

prepare 文の構文図
preparedStatementID
prepare 文が実行時に作成する SQL コードを識別する任意の文字ストリング。 EGL execute 文、open 文、 または get 文で、この ID を使用できます。
stringExpression
ストリング式の形式で有効な SQL 文。 リテラル・ストリングは引用符で囲みます。また、ストリング変数に結合するには「::」演算子を使用します (このトピックの『例』を参照)。
SQLRecordVariable
SQL レコード変数の名前。 EGL エディターで、 stringExpression を作成するためのキューを用意できます (「EGL プログラマー・ガイド」の コンテンツ・アシスト を参照)。この名前にエラー条件がないかをテストできます (このトピックの『例』を参照)。

動的 SQL と prepare 文

動的 SQL の処理には、prepare ステートメントを使用するのが一般的な方法です。 指定するストリング式には、実行時にのみ値を知ることができる変数を含めることができます。これは、プログラムでの強力なオプションになります。

動的 SQL の一般的な使用法の 1 つが、ユーザー制御による照会です。 例えば、ユーザーがチェック・ボックスを選択して、レポートに情報を組み込む場合があります。 また、WHERE 文節を使用して、プログラムが表示する顧客レコードを決める場合もあります。 いずれの場合も、前もってユーザーが選択するデータを知ることはできません。

ストリング式のホスト変数にプレースホルダーとして疑問符を使用することもできます (『ホスト変数』を参照)。 準備済み文を実行するときに、prepare 文、get 文、または open 文の using 文節の一部として、これらの変数をリストしてください。 2 番目の例は、この処理を示しています。 プレースホルダーとして使用しているすべての疑問符にホスト変数を指定する必要があります。 また、これらの変数の用途を知っておく必要もあります。

以下の例では、メニューからユーザーが選択した項目に基づいてストリングを動的に作成します。
query STRING;
fieldName STRING; 
isFirstField BOOLEAN;  

query = "SELECT "; 
isFirstField = true; 

// 関数がユーザーの選択したフィールド名を提供します
// すべてが使用されると -1 を戻します
while ((nextFieldName(fieldName)) == 0)  // fieldName を設定します
   if (!isFirstField)  // SELECT に複数のフィールドがあります
      query ::= ", ";
   end
   query ::= fieldName;
   isFirstField = false; 
end // (期間を)

// クエリーを終了
query ::= "FROM Customer WHERE customer_number = ?"; 
prepare myPreparedStatement from query;
prepare 文の実行後、次の例のように、 レコード名で入出力エラー値を照らし合わせ、その文が成功したかどうかを判別できます。 この例では、ホスト変数のプレースホルダーとして疑問符を使用しています (『ホスト変数』を参照)。
  try
    prepare prep01 from  
     "INSERT INTO " :: aTableName :: 
     "(customer_number, customer_name) " ::
     "VALUE ?, ?"
     for myCustomer;

  onException(sqlEx SQLException)
    if (myCustomer is unique)
      myErrorHandler(8);
    else
      myErrorHandler(sqlEx);
    end
  end
  
  try
    execute myStatement 
    using myRecord.empnum,
          myRecord.empname;
  onException(sqlEx SQLException)
    myErrorHandler(sqlEx);
  end

前の例のように、ホスト変数の代わりに疑問符 (?) を使用できます。 実行時に使用されるホスト変数の名前は、準備済み文を実行する execute 文、open 文、または get 文の using 文節に配置されます。

結果セットの行で機能する prepare 文には、WHERE CURRENT OF resultSetIdentifier という形式の句を含めることができます。 この手法は、次の条件が当てはまる場合にのみ有効です。
  • 句がリテラル中にコード化されている。
  • prepare 文が実行されたときに、 結果セットがオープンされている。
X1 が open ステートメントからの結果セット ID であると仮定します。 次の例は、動的な準備済み文を作成して実行します。
	 prepare prep02 from
    "update myTable " ::
    "set empname = ?,  empphone = ?  where current of x1" ;
 
  execute prep02 using empname, empphone;
  freeSQL prep02;

互換性

表 1. prepare の互換性に関する考慮事項
プラットフォーム 問題
COBOL 生成およびデバッグ 動的 SQL 準備済み文では、 すべての ID および SQLRecord 変数を、それらを参照し使用する同一関数内で宣言する必要があります。この制限は、Java™ 生成には適用されないため、 ID は名前空間内の任意の場所に置くことができます。
Java 生成 文を準備する際に使用するストリング式が何らかの理由により無効である場合、prepare 文が失敗するとは限りません。 代わりに、EGL は、初めてその準備済み文を使用する際に SQLException をスローする場合があります。
Oracle 提供の JDBC ドライバーを使用して、以下のように構造化されているコードを処理すると、問題が発生する場合があります。
   prepare q from "select a, b from c where myColumn > ?";
   get into x, y with q using myVar;

発生する問題とは、行を確実に取得するために、変数の長さをデータベース列と同じ長さに設定することが必要になる場合があるということです。

以下のケースでは行は取得されません。
  • prepare ステートメントに WHERE 節がある SQL SELECT ステートメントが組み込まれている。
  • WHERE 節が SQL タイプ CHAR の列を何らかの方法でホスト変数と比較する。
  • 準備されたステートメントを実行するステートメントで、ホスト変数が EGL タイプの CHAR である。
  • データベース列の長さが、変数の長さと異なる。
  • Oracle が提供する JDBC ドライバーを使用する。

この資料の執筆時点で、この問題は次の Web サイトのセクション 11.3.7.4 に記載されています。 http://download.oracle.com/docs/cd/B14117_01/java.101/b10979/datacc.htm


フィードバック