Share via


Vorbereitete Ausführung

Die ODBC-API definiert eine vorbereitete Ausführung als einen Weg, den Analyse- und Kompilieraufwand, der mit dem wiederholten Ausführen einer Transact-SQL-Anweisung einhergeht, zu reduzieren. Die Anwendung erstellt eine Zeichenfolge, die eine SQL-Anweisung enthält, und führt diese Anweisung dann in zwei Phasen aus. Sie ruft einmal SQLPrepare auf, um die Anweisung zu analysieren und von Database Engine (Datenbankmodul) in einen Ausführungsplan kompilieren zu lassen. Dann wird SQLExecute für jede Ausführung des vorbereiteten Ausführungsplans aufgerufen. Dadurch wird bei jeder Ausführung der mit der Analyse und Kompilierung verbundene Aufwand reduziert. Die vorbereitete Ausführung wird in Anwendungen häufig verwendet, um dieselbe parametrisierte SQL-Anweisung mehrfach auszuführen.

Bei den meisten Datenbanken ist die vorbereitete Ausführung schneller als eine direkte Ausführung von Anweisungen, die mehr als drei- oder viermal ausgeführt werden, hauptsächlich da die Anweisung nur einmal kompiliert wird, während die direkt ausgeführten Anweisungen bei jeder Ausführung kompiliert werden. Die vorbereitete Ausführung kann auch zu einer Reduzierung des Netzwerkverkehrs beitragen, da der Treiber bei jeder Ausführung der Anweisung eine Ausführungsplan-ID und die Parameterwerte an die Datenquelle senden kann, anstatt die gesamte SQL-Anweisung zu senden.

SQL Server 2000 und später reduziert den Leistungsunterschied zwischen direkter und vorbereiteter Ausführung mithilfe verbesserter Algorithmen zur Erkennung und Wiederverwendung von Ausführungsplänen aus SQLExecDirect. Dadurch stehen einige der Leistungsvorteile einer vorbereiteten Ausführung auch für direkt ausgeführte Anweisungen zur Verfügung. Weitere Informationen hierzu finden Sie unter Direkte Ausführung.

SQL Server 2000 und später bietet auch systemeigene Unterstützung für die vorbereitete Ausführung. Ein Ausführungsplan baut auf SQLPrepare auf und wird ausgeführt, wenn SQLExecute aufgerufen wird. Da SQL Server 2000 und später nicht zum Erstellen temporär gespeicherter Prozeduren auf SQLPrepare erforderlich ist, kommt es nicht zu einem zusätzlichen Aufwand in den Systemtabellen in tempdb.

Aus Leistungsgründen wird die Anweisungsvorbereitung verzögert, bis SQLExecute aufgerufen wird oder ein Metaeigenschaftsvorgang (z. B. SQLDescribeCol oder SQLDescribeParam in ODBC) ausgeführt wird. Dies ist das Standardverhalten. Fehler in der vorbereiteten Anweisung werden erst dann erkannt, wenn die Anweisung ausgeführt oder ein Metaeigenschaftsvorgang durchgeführt wird. Wenn Sie das SQL Server Native Client ODBC-treiberspezifische Anweisungsattribut SQL_SOPT_SS_DEFER_PREPARE auf SQL_DP_OFF setzen, kann dieses Standardverhalten deaktiviert werden.

Bei verzögertem Vorbereiten wird durch das Aufrufen von SQLDescribeCol oder SQLDescribeParam vor dem Aufrufen von SQLExecute ein zusätzlicher Roundtrip zum Server erstellt. Bei SQLDescribeCol entfernt der Treiber die WHERE-Klausel aus der Abfrage und sendet sie an den Server mit SET FMTONLY ON, um die Beschreibung der Spalten im ersten Ergebnissatz abzurufen, der von der Abfrage zurückgegeben wird. Bei SQLDescribeParam ruft der Treiber den Server ab, um eine Beschreibung der Ausdrücke oder Spalten abzurufen, auf die von einem Parametermarker in der Abfrage verwiesen wird. Bei dieser Methode kommt es auch zu einigen Einschränkungen, z. B. können keine Parameter in Unterabfragen gelöst werden.

Ein übermäßiger Gebrauch von SQLPrepare mit dem SQL Server Native Client ODBC-Treiber lässt die Leistung sinken, vor allem wenn eine Verbindung zu früheren Versionen von SQL Server besteht. Die vorbereitete Ausführung sollte nicht für Anwendungen verwendet werden, die nur einmal ausgeführt werden. Die vorbereitete Ausführung dauert länger als eine direkte Ausführung für eine einzelne Ausführung einer Anweisung, da ein zusätzlicher Netzwerkroundtrip vom Client zum Server erforderlich ist. Auf früheren Versionen von SQL Server wird auch eine temporär gespeicherte Prozedur erstellt.

Vorbereitete Anweisungen können nicht zum Erstellen von temporären Objekten auf SQL Server 2000 oder später bzw. auf früheren Version von SQL Server verwendet werden, wenn die Option zum Erstellen von gespeicherten Prozeduren aktiv ist. Wenn diese Option aktiv ist, wird die vorbereitete Anweisung in eine temporär gespeicherte Prozedur integriert, die beim Abrufen von SQLExecute ausgeführt wird. Jedes während der Ausführung einer gespeicherten Prozedur erstellte temporäre Objekt wird automatisch gelöscht, wenn die Prozedur abgeschlossen wurde. Bei den beiden folgenden Beispielen wird die temporäre Tabelle #sometable nicht erstellt, wenn die Option zum Erstellen gespeicherter Prozeduren für die Vorbereitung aktiv ist:

SQLPrepare(hstmt,
   "CREATE TABLE #sometable(cola int, colb char(8))",
   SQL_NTS);
SQLExecute(hstmt);

oder

SQLPrepare(hstmt,
   "SELECT * FROM Authors INTO #sometable",
   SQL_NTS);
SQLExecute(hstmt);

Einige ältere ODBC-Anwendungen verwendeten SQLPrepare jedes Mal, wenn SQLBindParameter verwendet wurde. Mit SQLBindParameter muss nicht SQLPrepare verwendet werden, es kann jedoch mit SQLExecDirect verwendet werden. So kann beispielsweise SQLExecDirect mit SQLBindParameter verwendet werden, um den Rückgabecode oder die Ausgabeparameter aus einer gespeicherten Prozedur, die nur einmal ausgeführt wird, abzurufen. Verwenden Sie SQLPrepare nicht mit SQLBindParameter, es sei denn, die gleiche Anweisung wird mehrmals ausgeführt.

Siehe auch

Konzepte