Ziehpunkte

Handles sind undurchsichtige, 32-Bit-Werte, die ein bestimmtes Element identifizieren; in ODBC kann es sich bei diesem Element um eine Umgebung, eine Verbindung, eine Anweisung oder einen Deskriptor handeln. Wenn die Anwendung SQLAllocHandle aufruft, erstellt der Treiber-Manager oder -Treiber ein neues Element des angegebenen Typs und gibt dessen Handle an die Anwendung zurück. Die Anwendung verwendet später das Handle, um dieses Element beim Aufrufen von ODBC-Funktionen zu identifizieren. Der Treiber-Manager und der Treiber verwenden das Handle, um Informationen zum Element zu finden.

Der folgende Code verwendet beispielsweise zwei Anweisungshandles (hstmtOrder und hstmtLine), um die Anweisungen zu identifizieren, für die Resultsets von Verkaufsaufträgen und Verkaufsauftragszeilennummern erstellt werden sollen. Später werden diese Handles verwendet, um zu identifizieren, aus welchem Resultset Daten abgerufen werden sollen.

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);  

Handles sind nur für die ODBC-Komponente sinnvoll, die sie erstellt hat; d. h., nur der Treiber-Manager kann Treiber-Manager-Handles interpretieren, und nur ein Treiber kann seine eigenen Handles interpretieren.

Angenommen, der Treiber im vorherigen Beispiel weist eine Struktur zum Speichern von Informationen zu einer Anweisung zu und gibt den Zeiger auf diese Struktur als Anweisungshandle zurück. Wenn die Anwendung SQLPrepare aufruft, übergibt sie eine SQL-Anweisung und das Handle der Anweisung, die für Verkaufsauftragszeilennummern verwendet wird. Der Treiber sendet die SQL-Anweisung an die Datenquelle, die sie vorbereitet und einen Zugriffsplanbezeichner zurückgibt. Der Treiber verwendet das Handle, um die Struktur zu finden, in der dieser Bezeichner gespeichert werden soll.

Wenn die Anwendung später SQLExecute aufruft, um den Resultset von Zeilennummern für einen bestimmten Verkaufsauftrag zu generieren, wird derselbe Handle übergeben. Der Treiber verwendet das Handle zum Abrufen des Zugriffsplanbezeichners aus der Struktur. Er sendet den Bezeichner an die Datenquelle, um ihm mitzuteilen, welcher Plan ausgeführt werden soll.

ODBC verfügt über zwei Handlesebenen: Treiber-Manager-Handles und Treiberhandles. Die Anwendung verwendet Treiber-Manager-Handles beim Aufrufen von ODBC-Funktionen, da sie diese Funktionen im Treiber-Manager aufruft. Der Treiber-Manager verwendet dieses Handle, um das entsprechende Treiberhandle zu finden, und verwendet das Treiberhandle beim Aufrufen der Funktion im Treiber. Ein Beispiel für die Verwendung von Treiber- und Treiber-Manager-Handles finden Sie unter "Rolle des Treiber-Managers im Verbindungsprozess".

Dass es zwei Handles-Ebenen gibt, ist ein Artefakt der ODBC-Architektur; in den meisten Fällen ist es für die Anwendung oder den Treiber nicht relevant. Obwohl es in der Regel keinen Grund gibt, ist es für die Anwendung möglich, die Treiberhandles durch Aufrufen von SQLGetInfo zu ermitteln.

In diesem Abschnitt werden die folgenden Themen behandelt: