ステートメントの実行
ステートメントを実行する方法は、データベース エンジンによってコンパイル (準備) されるタイミングと、ステートメントを定義するユーザーに応じて 4 つあります。
直接実行 アプリケーションは SQL ステートメントを定義します。 これは、シングル ステップで実行時に準備され、実行されます。
準備された実行 アプリケーションは、SQL ステートメントを定義します。 これは、別の手順で実行時に準備され、実行されます。 ステートメントは 1 回準備して複数回実行できます。
プロシージャ アプリケーションは、開発時に 1 つ以上の SQL ステートメントを定義してコンパイルし、これらのステートメントをプロシージャとしてデータ ソースに格納できます。 プロシージャは実行時に 1 回以上実行されます。 アプリケーションは、カタログ関数を使用することで、使用可能なストアド プロシージャを列挙できます。
カタログ関数 ドライバー ライターは、定義済みの結果セットを返す関数を作成します。 通常、この関数は定義済みの SQL ステートメントを送信するか、この目的のために作成されたプロシージャを呼び出します。 この関数は、実行時に 1 回以上実行されます。
(ステートメント ハンドルによって識別される) 特定のステートメントは、任意の回数実行できます。 ステートメントは、さまざまな SQL ステートメントで実行することも、同じ SQL ステートメントを使用して繰り返し実行することもできます。 たとえば、次のコードでは、同じステートメント ハンドル (hstmt1) を使用して、セールス データベース内のテーブルを取得して表示します。 その後、このハンドルを再利用して、ユーザーが選択したテーブル内の列を取得します。
SQLHSTMT hstmt1;
SQLCHAR * Table;
// Create a result set of all tables in the Sales database.
SQLTables(hstmt1, "Sales", SQL_NTS, "sysadmin", SQL_NTS, NULL, 0, NULL, 0);
// Fetch and display the table names; then close the cursor.
// Code not shown.
// Have the user select a particular table.
SelectTable(Table);
// Reuse hstmt1 to create a result set of all columns in Table.
SQLColumns(hstmt1, "Sales", SQL_NTS, "sysadmin", SQL_NTS, Table, SQL_NTS, NULL, 0);
// Fetch and display the column names in Table; then close the cursor.
// Code not shown.
次のコードは、同じステートメントを繰り返し実行してテーブルから行を削除するために 1 つのハンドルを使用する方法を示しています。
SQLHSTMT hstmt1;
SQLUINTEGER OrderID;
SQLINTEGER OrderIDInd = 0;
// Prepare a statement to delete orders from the Orders table.
SQLPrepare(hstmt1, "DELETE FROM Orders WHERE OrderID = ?", SQL_NTS);
// Bind OrderID to the parameter for the OrderID column.
SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&OrderID, 0, &OrderIDInd);
// Repeatedly execute hstmt1 with different values of OrderID.
while ((OrderID = GetOrderID()) != 0) {
SQLExecute(hstmt1);
}
多くのドライバーの場合、ステートメントの割り当てはコストの高いタスクであるため、通常、既存のステートメントを解放して新しいステートメントを割り当てるよりも、このように同じステートメントを再利用する方が効率的です。 ステートメントに結果セットを作成するアプリケーションでは、ステートメントを再実行する前に、結果セットの上にカーソルを閉じるよう注意する必要があります。詳細については、「カーソルを閉じる」を参照してください。
また、ステートメントを再利用すると、一度にアクティブにできるステートメントの数に関する一部のドライバーの制限を回避するようにアプリケーションが強制されます。 "active" の正確な定義はドライバー固有ですが、多くの場合、準備または実行され、使用可能な結果が残っているステートメントを参照します。 たとえば、INSERT ステートメントが準備された後は、一般にアクティブと見なされます。SELECT ステートメントが実行され、カーソルがまだ開かれた後は、一般にアクティブと見なされます。CREATE TABLE ステートメントが実行された後は、一般にアクティブとは見なされません。
アプリケーションは、SQL_MAX_CONCURRENT_ACTIVITIES オプションを指定して SQLGetInfo を呼び出すことによって、1 回の接続でアクティブにできるステートメントの数を決定します。 アプリケーションでは、データ ソースへの複数の接続を開くことで、この制限よりもアクティブなステートメントを使用できます。ただし、接続はコストがかかる可能性があるため、パフォーマンスへの影響を考慮する必要があります。
アプリケーションでは、SQL_ATTR_QUERY_TIMEOUT ステートメント属性を使用してステートメントを実行するために割り当てられる時間を制限できます。 データ ソースが結果セットを返す前にタイムアウト期間が経過すると、SQL ステートメントを実行する関数は SQLSTATE HYT00 (タイムアウト期限切れ) を返します。 既定では、タイムアウトはありません。
このセクションでは、次のトピックを扱います。