ODBC API は、Transact-SQL ステートメントの繰り返し実行に関連する解析とコンパイルのオーバーヘッドを軽減する方法として、準備された実行を定義します。 アプリケーションは、SQL ステートメントを含む文字列をビルドし、2 つのステージで実行します。 SQLPrepare 関数を 1 回呼び出して、データベース エンジンによってステートメントを解析して実行プランにコンパイルします。 次に、準備された実行プランの実行ごとに SQLExecute を呼び出します。 これにより、各実行の解析とコンパイルのオーバーヘッドが節約されます。 準備された実行は、パラメーター化された同じ SQL ステートメントを繰り返し実行するためにアプリケーションで一般的に使用されます。
ほとんどのデータベースでは、準備された実行は、主にステートメントが 1 回だけコンパイルされ、直接実行されるステートメントは実行されるたびにコンパイルされるため、3 回または 4 回以上実行されるステートメントの直接実行よりも高速です。 また、準備された実行により、ドライバーは SQL ステートメント全体ではなく実行プラン識別子とパラメーター値を、ステートメントが実行されるたびにデータ ソースに送信できるため、ネットワーク トラフィックが減少する可能性があります。
SQL Server では、 SQLExecDirect から実行プランを検出して再利用するためのアルゴリズムが改善され、直接実行と準備実行のパフォーマンスの違いが軽減されます。 これにより、準備された実行のパフォーマンス上の利点の一部が、直接実行されるステートメントで使用できるようになります。 詳細については、「 直接実行」を参照してください。
SQL Server では、準備された実行のネイティブ サポートも提供されます。 実行プランは SQLPrepare 上に構築され、 SQLExecute が呼び出されたときに後で実行されます。 SQL Server は SQLPrepare で一時ストアド プロシージャをビルドする必要がないため、 tempdb のシステム テーブルに余分なオーバーヘッドはありません。
パフォーマンス上の理由から、 SQLExecute が呼び出されるか、メタプロパティ操作 (ODBC の SQLDescribeCol や SQLDescribeParam など) が実行されるまで 、 ステートメントの準備は遅延されます。 これが既定の動作です。 準備中のステートメント内のエラーは、ステートメントが実行されるか、メタプロパティ操作が実行されるまで認識されません。 SQL Server Native Client ODBC ドライバー固有のステートメント属性SQL_SOPT_SS_DEFER_PREPAREをSQL_DP_OFFに設定すると、この既定の動作を無効にすることができます。
遅延準備の場合、SQLExecute を呼び出す前に SQLDescribeCol または SQLDescribeParam を呼び出すと、サーバーへの余分なラウンドトリップが生成されます。 SQLDescribeCol では、ドライバーはクエリから WHERE 句を削除し、SET FMTONLY ON を使用してサーバーに送信して、クエリによって返される最初の結果セット内の列の説明を取得します。 SQLDescribeParam では、ドライバーはサーバーを呼び出して、クエリ内の任意のパラメーター マーカーによって参照される式または列の説明を取得します。 このメソッドには、サブクエリのパラメーターを解決できないなど、いくつかの制限もあります。
SQL Server Native Client ODBC ドライバーで SQLPrepare を過剰に使用すると、特に以前のバージョンの SQL Server に接続している場合、パフォーマンスが低下します。 準備された実行は、1 回実行されるステートメントには使用しないでください。 準備された実行は、クライアントからサーバーへの追加のネットワーク ラウンドトリップが必要なため、ステートメントの 1 回の実行に対する直接実行よりも遅くなります。 以前のバージョンの SQL Server では、一時ストアド プロシージャも生成されます。
準備済みステートメントを使用して SQL Server 上に一時オブジェクトを作成することはできません。
一部の初期 ODBC アプリケーションでは、SQLBindParameter が使用されるたびに SQLPrepare が使用されていました。 SQLBindParameter は SQLPrepare を使用する必要はありません。 SQLExecDirect と共に使用できます。 たとえば、SQLBindParameter で SQLExecDirect を使用して、1 回だけ実行されるストアド プロシージャからリターン コードまたは出力パラメーターを取得します。 同じステートメントが複数回実行されない限り、SQLBindParameter で SQLPrepare を使用しないでください。