準備実行 ODBC

準備された実行は、ステートメントを複数回実行する効率的な方法です。 ステートメントは、最初にコンパイルされるか、アクセス プランに 準備されます 。 アクセス プランは、後で 1 回以上実行されます。 アクセス・プランの詳細については、SQLステートメントの処理を参照してください

準備された実行は、パラメーター化された同じSQLステートメントを繰り返し実行するために、垂直アプリケーションとカスタム アプリケーションで一般的に使用されます。 たとえば、次のコードでは、さまざまな部分の価格を更新するステートメントを準備します。 その後、ステートメントは毎回異なるパラメーター値で複数回実行されます。

SQLREAL       Price;  
SQLUINTEGER   PartID;  
SQLINTEGER    PartIDInd = 0, PriceInd = 0;  
  
// Prepare a statement to update salaries in the Employees table.  
SQLPrepare(hstmt, "UPDATE Parts SET Price = ? WHERE PartID = ?", SQL_NTS);  
  
// Bind Price to the parameter for the Price column and PartID to  
// the parameter for the PartID column.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 10, 0,  
                  &PartID, 0, &PartIDInd);  
  
// Repeatedly execute the statement.  
while (GetPrice(&PartID, &Price)) {  
   SQLExecute(hstmt);  
}  

準備された実行は、主にステートメントが 1 回だけコンパイルされるため、複数回実行されるステートメントの直接実行よりも高速です。直接実行されるステートメントは、実行されるたびにコンパイルされます。 また、データ ソースがアクセス プラン識別子をサポートしている場合、ドライバーはステートメント全体ではなく、SQL ステートメント全体ではなく、ステートメントが実行されるたびにデータ ソースにアクセス プラン識別子を送信できるため、準備された実行によってネットワーク トラフィックが減少する可能性があります。

アプリケーションは、ステートメントの準備後と実行前に、結果セットのメタデータを取得できます。 ただし、準備された実行されていないステートメントのメタデータを返すと、一部のドライバーではコストがかかり、可能な場合は相互運用可能なアプリケーションで回避する必要があります。 詳細については、「 結果セットのメタデータ」を参照してください。

準備実行は、1 回しか実行されないステートメントには使用しないでください。 このようなステートメントの場合、ODBC 関数呼び出しを追加する必要があるため、直接実行よりも若干遅くなります。

重要

SQLEndTran を明示的に呼び出すか、自動コミット モードで作業することによってトランザクションをコミットまたはロールバックすると、一部のデータ ソースは接続上のすべてのステートメントのアクセス プランを削除します。 詳細については、 SQLGetInfo 関数の説明のSQL_CURSOR_COMMIT_BEHAVIORオプションとSQL_CURSOR_ROLLBACK_BEHAVIOR オプションを参照してください。

ステートメントを準備して実行するために、アプリケーションは次の手順を実行します。

  1. SQLPrepare を呼び出し、SQL ステートメントを含む文字列を渡します。

  2. 任意のパラメーターの値を設定します。 パラメーターは、実際には、ステートメントの準備の前または後に設定できます。 詳細については、このセクションで後述する ステートメント パラメーターを参照してください。

  3. SQLExecute を呼び出し、必要な追加処理 (データのフェッチなど) を実行します。

  4. 必要に応じて手順 2 と 3 を繰り返します。

  5. SQLPrepare が呼び出されると、ドライバーは次のようになります。

    • ステートメントを解析せずにデータ ソースのSQL文法を使用するように、SQL ステートメントを変更します。 これには、ODBC のエスケープ シーケンスで説明されている エスケープ シーケンスの置き換えも含まれます。 アプリケーションは、SQLNativeSql を呼び出すことによって、SQL ステートメントの変更された形式を取得できます。 SQL_ATTR_NOSCAN ステートメント属性が設定されている場合、エスケープ シーケンスは置き換えられません。

    • 準備のためにステートメントをデータ ソースに送信します。

    • 後で実行するために返されたアクセス プラン識別子を格納するか (準備が成功した場合)、またはエラー (準備に失敗した場合) を返します。 エラーには、SQLSTATE 42000 (構文エラーまたはアクセス違反) などの構文エラーや、SQLSTATE 42S02 (ベース テーブルまたはビューが見つからない) などのセマンティック エラーが含まれます。

      注意

      一部のドライバーは、この時点ではエラーを返しませんが、代わりにステートメントが実行されたとき、またはカタログ関数が呼び出されたときにエラーを返します。 したがって、 SQLPrepare は実際に失敗した場合に成功したように見える場合があります。

  6. SQLExecute が呼び出されると、ドライバーは次のようになります。

    • 現在のパラメーター値を取得し、必要に応じて変換します。 詳細については、このセクションで後述する ステートメント パラメーターを参照してください。

    • アクセス プラン識別子と変換されたパラメーター値をデータ ソースに送信します。

    • エラーを返します。 これらは通常、SQLSTATE 24000 (無効なカーソル状態) などの実行時エラーです。 ただし、一部のドライバーは、この時点で構文エラーとセマンティック エラーを返します。

データ ソースがステートメントの準備をサポートしていない場合、ドライバーは可能な限りそれをエミュレートする必要があります。 たとえば、 SQLPrepare が呼び出されたときにドライバーが何も行わない場合があり、 SQLExecute が呼び出されたときにステートメントを直接実行します。

データ ソースが実行なしの構文チェックをサポートしている場合、ドライバーは 、SQLPrepare が呼び出されたときにチェックするステートメントを送信し、 SQLExecute が呼び出されたときに実行するステートメントを送信することがあります。

ドライバーは、ステートメントの準備をエミュレートできない場合は、 SQLPrepare が呼び出されたときにステートメントを格納し、 SQLExecute が呼び出されたときに実行のために送信します。

エミュレートされたステートメントの準備は完璧ではないので、 SQLExecuteSQLPrepare によって通常返されるすべてのエラーを返すことができます。