ステートメントの実行

ステートメントを実行する方法は、データベース エンジンによってコンパイル (準備) されるタイミングと、ステートメントを定義するユーザーに応じて 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 (タイムアウト期限切れ) を返します。 既定では、タイムアウトはありません。

このセクションでは、次のトピックを扱います。