ハンドル

ハンドルは、特定の項目を識別する不透明な 32 ビット値です。ODBC では、この項目には環境、接続、ステートメント、または記述子を指定できます。 アプリが SQLAllocHandle を呼び出すと、ドライバー マネージャーまたはドライバーは、指定した型の新しい項目を作成し、そのハンドルをアプリに返します。 アプリは、後で ODBC 関数を呼び出すときにハンドルを使用してその項目を識別します。 ドライバー マネージャーとドライバーは、ハンドルを使用して項目に関する情報を検索します。

たとえば、次のコードでは、2 つのステートメント ハンドル (hstmtOrderhstmtLine) を使用して、販売注文と販売注文明細行番号の結果セットを作成するステートメントを識別します。 後でこれらのハンドルを使用して、データをフェッチする結果セットを識別します。

SQLHSTMT      hstmtOrder, hstmtLine; // Statement handles.  
SQLUINTEGER   OrderID;  
SQLINTEGER    OrderIDInd = 0;  
SQLRETURN     rc;  
  
// Prepare the statement that retrieves line number information.  
SQLPrepare(hstmtLine, "SELECT * FROM Lines WHERE OrderID = ?", SQL_NTS);  
  
// Bind OrderID to the parameter in the preceding statement.  
SQLBindParameter(hstmtLine, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,  
               &OrderID, 0, &OrderIDInd);  
  
// Bind the result sets for the Order table and the Lines table. Bind  
// OrderID to the OrderID column in the Orders table. When each row is  
// fetched, OrderID will contain the current order ID, which will then be  
// passed as a parameter to the statement tofetch line number  
// information. Code not shown.  
  
// Create a result set of sales orders.  
SQLExecDirect(hstmtOrder, "SELECT * FROM Orders", SQL_NTS);  
  
// Fetch and display the sales order data. Code to check if rc equals  
// SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.  
while ((rc = SQLFetch(hstmtOrder)) != SQL_NO_DATA) {  
   // Display the sales order data. Code not shown.  
  
   // Create a result set of line numbers for the current sales order.  
   SQLExecute(hstmtLine);  
  
   // Fetch and display the sales order line number data. Code to check  
   // if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.  
   while ((rc = SQLFetch(hstmtLine)) != SQL_NO_DATA) {  
      // Display the sales order line number data. Code not shown.  
   }  
  
   // Close the sales order line number result set.  
   SQLCloseCursor(hstmtLine);  
}  
  
// Close the sales order result set.  
SQLCloseCursor(hstmtOrder);  

ハンドルは、ハンドルを作成した ODBC コンポーネントにのみ意味があります。つまり、ドライバー マネージャーのみがドライバー マネージャーハンドルを解釈でき、ドライバーのみが独自のハンドルを解釈できます。

たとえば、前の例のドライバーは、ステートメントに関する情報を格納する構造体を割り当て、ステートメント ハンドルとしてこの構造体へのポインターを返します。 アプリケーションが SQLPrepare を呼び出すと、SQL ステートメントと販売注文行番号に使用されるステートメントのハンドルが渡されます。 ドライバーは、SQL ステートメントをデータ ソースに送信します。データ ソースは SQL ステートメントを準備し、アクセス プラン識別子を返します。 ドライバーは、ハンドルを使用して、この識別子を格納する構造体を検索します。

その後、アプリが SQLExecute を呼び出して特定の販売注文の行番号の結果セットを生成すると、同じハンドルが渡されます。 ドライバーは、構造体からアクセス プラン識別子を取得するハンドルを使用します。 識別子をデータ ソースに送信して、実行するプランを伝えます。

ODBC には、ドライバー マネージャー ハンドルとドライバー ハンドルという 2 つのレベルのハンドルがあります。 アプリは、ドライバー マネージャーでこれらの関数を呼び出すので、ODBC 関数を呼び出すときにドライバー マネージャー ハンドルを使用します。 ドライバー マネージャーは、このハンドルを使用して、対応するドライバー ハンドルを検索し、ドライバーで関数を呼び出すときにドライバー ハンドルを使用します。 ドライバーとドライバー マネージャーハンドルの使用方法の例については、「接続プロセスにおけるドライバー マネージャーの役割」を参照してください。

2 つのレベルのハンドルがあることは、ODBC アーキテクチャの成果物です。ほとんどの場合、アプリまたはドライバーには関係ありません。 通常、これを行う理由はありませんが、アプリは SQLGetInfo を呼び出すことによってドライバーハンドルを決定できます。

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