Vorbereitete Ausführungs-ODBC

Die vorbereitete Ausführung ist eine effiziente Möglichkeit, eine Anweisung mehrmals auszuführen. Die Anweisung wird zuerst in einem Zugriffsplan kompiliert oder vorbereitet . Der Zugriffsplan wird dann zu einem späteren Zeitpunkt einmal ausgeführt. Weitere Informationen zu Zugriffsplänen finden Sie unter Verarbeiten einer SQL-Anweisung.

Die vorbereitete Ausführung wird häufig von vertikalen und benutzerdefinierten Anwendungen verwendet, um wiederholt dieselbe parametrisierte SQL-Anweisung auszuführen. Der folgende Code bereitet beispielsweise eine Anweisung vor, um die Preise verschiedener Teile zu aktualisieren. Anschließend wird die Anweisung mehrmals mit unterschiedlichen Parameterwerten ausgeführt.

SQLREAL       Price;  
SQLUINTEGER   PartID;  
SQLINTEGER    PartIDInd = 0, PriceInd = 0;  
  
// Prepare a statement to update salaries in the Employees table.  
SQLPrepare(hstmt, "UPDATE Parts SET Price = ? WHERE PartID = ?", SQL_NTS);  
  
// Bind Price to the parameter for the Price column and PartID to  
// the parameter for the PartID column.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 10, 0,  
                  &PartID, 0, &PartIDInd);  
  
// Repeatedly execute the statement.  
while (GetPrice(&PartID, &Price)) {  
   SQLExecute(hstmt);  
}  

Die vorbereitete Ausführung ist schneller als die direkte Ausführung von Anweisungen, die mehrmals ausgeführt werden, hauptsächlich weil die Anweisung nur einmal kompiliert wird; Anweisungen, die direkt ausgeführt werden, werden jedes Mal kompiliert, wenn sie ausgeführt werden. Die vorbereitete Ausführung kann auch eine Verringerung des Netzwerkdatenverkehrs ermöglichen, da der Treiber bei jeder Ausführung der Anweisung eine Zugriffsplan-ID an die Datenquelle senden kann, anstatt eine gesamte SQL-Anweisung, wenn die Datenquelle Zugriffsplan-IDs unterstützt.

Die Anwendung kann die Metadaten für das Resultset abrufen, nachdem die Anweisung vorbereitet wurde und bevor sie ausgeführt wird. Das Zurückgeben von Metadaten für vorbereitete, nicht ausgeführte Anweisungen ist jedoch für einige Treiber teuer und sollte nach Möglichkeit von interoperablen Anwendungen vermieden werden. Weitere Informationen finden Sie unter "Resultset Metadata".

Die vorbereitete Ausführung sollte nicht für Anwendungen verwendet werden, die nur einmal ausgeführt werden. Für solche Anweisungen ist sie etwas langsamer als die direkte Ausführung, da ein zusätzlicher ODBC-Funktionsaufruf erforderlich ist.

Wichtig

Commit oder Rollback einer Transaktion, entweder durch explizites Aufrufen von SQLEndTran oder durch Arbeiten im Automatischen Commit-Modus bewirkt, dass einige Datenquellen die Zugriffspläne für alle Anweisungen in einer Verbindung löschen. Weitere Informationen finden Sie unter den optionen SQL_CURSOR_COMMIT_BEHAVIOR und SQL_CURSOR_ROLLBACK_BEHAVIOR in der SQLGetInfo-Funktionsbeschreibung .

Um eine Anweisung vorzubereiten und auszuführen, führt die Anwendung Folgendes aus:

  1. Ruft SQLPrepare auf und übergibt sie eine Zeichenfolge, die die SQL-Anweisung enthält.

  2. Legt die Werte aller Parameter fest. Parameter können tatsächlich vor oder nach der Vorbereitung der Anweisung festgelegt werden. Weitere Informationen finden Sie unter "Anweisungsparameter" weiter unten in diesem Abschnitt.

  3. Ruft SQLExecute auf und führt alle erforderlichen zusätzlichen Verarbeitungen durch, z. B. das Abrufen von Daten.

  4. Wiederholt die Schritte 2 und 3 nach Bedarf.

  5. Wenn SQLPrepare aufgerufen wird, wird der Treiber:

    • Ändert die SQL-Anweisung so, dass die SQL-Grammatik der Datenquelle verwendet wird, ohne die Anweisung zu analysieren. Dies schließt das Ersetzen der escapesequenzen ein, die in Escapesequenzen in ODBC behandelt werden. Die Anwendung kann die geänderte Form einer SQL-Anweisung abrufen, indem SQLNativeSql aufgerufen wird. Escapesequenzen werden nicht ersetzt, wenn das attribut der SQL_ATTR_NOSCAN-Anweisung festgelegt ist.

    • Sendet die Anweisung zur Vorbereitung an die Datenquelle.

    • Speichert den zurückgegebenen Zugriffsplanbezeichner für die spätere Ausführung (sofern die Vorbereitung erfolgreich war) oder gibt Fehler zurück (wenn die Vorbereitung fehlgeschlagen ist). Fehler umfassen syntaktische Fehler wie SQLSTATE 42000 (Syntaxfehler oder Zugriffsverletzung) und semantische Fehler wie SQLSTATE 42S02 (Basistabelle oder Ansicht nicht gefunden).

      Hinweis

      Einige Treiber geben an diesem Punkt keine Fehler zurück, sondern geben sie stattdessen zurück, wenn die Anweisung ausgeführt wird oder wenn Katalogfunktionen aufgerufen werden. Daher könnte SQLPrepare möglicherweise erfolgreich sein, wenn sie tatsächlich fehlgeschlagen ist.

  6. Wenn SQLExecute aufgerufen wird, wird der Treiber:

    • Ruft die aktuellen Parameterwerte ab und konvertiert sie nach Bedarf. Weitere Informationen finden Sie unter "Anweisungsparameter" weiter unten in diesem Abschnitt.

    • Sendet den Zugriffsplanbezeichner und konvertierte Parameterwerte an die Datenquelle.

    • Gibt alle Fehler zurück. Dies sind im Allgemeinen Laufzeitfehler wie SQLSTATE 24000 (Ungültiger Cursorstatus). Einige Treiber geben jedoch an diesem Punkt syntaktische und semantische Fehler zurück.

Wenn die Datenquelle die Anweisungsvorbereitung nicht unterstützt, muss der Treiber sie soweit möglich emulieren. Beispielsweise kann der Treiber nichts tun, wenn SQLPrepare aufgerufen wird, und dann die direkte Ausführung der Anweisung ausführen, wenn SQLExecute aufgerufen wird.

Wenn die Datenquelle die Syntaxüberprüfung ohne Ausführung unterstützt, sendet der Treiber möglicherweise die Anweisung zur Überprüfung, wenn SQLPrepare aufgerufen wird, und sendet die Anweisung zur Ausführung, wenn SQLExecute aufgerufen wird.

Wenn der Treiber die Anweisungsvorbereitung nicht emulieren kann, speichert er die Anweisung, wenn SQLPrepare aufgerufen wird, und sendet sie zur Ausführung, wenn SQLExecute aufgerufen wird.

Da emulierte Anweisungsvorbereitung nicht perfekt ist, kann SQLExecute alle fehler zurückgeben, die normalerweise von SQLPrepare zurückgegeben werden.