Cursorimplementationen

Microsoft SQL Server 2005 unterstützt drei Cursorimplementierungen:

  • Transact-SQL-Cursor
    Diese basieren auf der DECLARE CURSOR-Syntax und werden hauptsächlich in Skripts, gespeicherten Prozeduren und Triggern von Transact-SQL verwendet. Transact-SQL-Cursor werden auf dem Server implementiert und durch Transact-SQL-Anweisungen verwaltet, die vom Client an den Server gesendet werden. Sie können auch in Batches, gespeicherten Prozeduren oder Triggern enthalten sein.
  • API-Servercursor (Application Programming Interface, Schnittstelle für Anwendungsprogrammierung)
    Sie unterstützen die API-Cursorfunktionen in OLE DB und ODBC. API-Servercursor werden auf dem Server implementiert. Wenn eine Clientanwendung eine API-Cursorfunktion aufruft, überträgt der SQL Native Client OLE DB-Anbieter oder der ODBC-Treiber die Anforderung an den Server, damit Maßnahmen für den API-Servercursor ergriffen werden.
  • Clientcursor
    Sie werden intern vom SQL Native Client-ODBC-Treiber und der DLL implementiert, die die ADO-API implementiert. Clientcursor werden durch Zwischenspeichern aller Resultsetzeilen auf dem Client implementiert. Wenn eine Clientanwendung eine API-Cursorfunktion aufruft, führen der SQL Native ODBC-Treiber oder die ADO-DLL die Cursoroperation auf den im Client zwischengespeicherten Resultsetzeilen aus.

Da Transact-SQL-Cursor und API-Servercursor auf dem Server implementiert werden, werden sie zusammen als Servercursor bezeichnet.

Sie sollten die Verwendung der unterschiedlichen Cursortypen nicht mischen. Wenn Sie die Anweisungen DECLARE CURSOR und OPEN von einer Anwendung ausführen, stellen Sie zuerst die API-Cursorattribute auf die Standardeinstellungen ein. Wenn Sie für die API-Cursorattribute Werte festlegen, die nicht ihre Standardwerte sind, und anschließend eine DECLARE CURSOR- und OPEN-Anweisung ausführen, wird SQL Server aufgefordert, einen API-Cursor über einen Transact-SQL-Cursor zuzuordnen. Sie sollten beispielsweise die ODBC-Attribute, die die Zuordnung eines keysetgesteuerten Cursors über einen Resultset aufrufen, nicht festlegen und anschließend dieses Anweisungshandle zum Ausführen von DECLARE CURSOR und OPEN verwenden, die einen INSENSITIVE-Cursor aufrufen.

Ein potenzieller Nachteil von Servercursorn liegt darin, dass sie zurzeit nicht alle Transact-SQL-Anweisungen unterstützen. Servercursor unterstützen keine Transact-SQL-Anweisungen, die mehrere Resultsets generieren. Sie können deshalb nicht verwendet werden, wenn die Anwendung eine gespeicherte Prozedur oder einen Batch ausführt, der mehrere SELECT-Anweisungen enthält. Servercursor unterstützen ebenfalls keine SQL-Anweisungen, die die Schlüsselwörter COMPUTE, COMPUTE BY, FOR BROWSE oder INTO enthalten.

Servercursor im Vergleich zu Standardresultsets

Das Verwenden eines Cursors ist weniger effizient als das Verwenden eines Standardresultsets. In einem Standardresultset ist das einzige Paket, das vom Client an den Server gesendet wird, das Paket, das die auszuführende Anweisung enthält. Beim Verwenden eines Servercursors muss jede FETCH-Anweisung vom Client an den Server gesendet werden; dort wird sie analysiert und in einen Ausführungsplan kompiliert.

Wenn eine Transact-SQL-Anweisung ein relativ kleines Resultset zurückgibt, das in dem Speicher, der der Clientanwendung zur Verfügung steht, zwischengespeichert werden kann, und Sie vor dem Ausführen der Anweisung wissen, dass Sie das gesamte Resultset abfragen müssen, sollten Sie ein Standardresultset verwenden. Verwenden Sie Servercursor nur dann, wenn Cursorvorgänge zum Unterstützen der Funktionalität der Anwendung erforderlich sind oder wenn vermutlich nur ein Teil des Resultsets abgerufen wird.

Servercursor im Vergleich zu Clientcursor

Es ergeben sich mehrere Vorteile aus dem Verwenden von Servercursorn anstelle von Clientcursorn:

  • Leistung
    Wenn Sie auf einen Teil der Daten im Cursor zugreifen möchten (wie dies bei vielen Durchsuchungsanwendungen typisch ist), erhalten Sie durch das Verwenden eines Servercursors eine optimale Leistung, da nur abgerufene Daten über das Netzwerk gesendet werden. Clientcursor legen das gesamte Resultset im Cache des Clients ab.
  • Zusätzliche Cursortypen
    Wenn der SQL Native Client-ODBC-Treiber ausschließlich Clientcursor verwenden würde, könnte er nur Vorwärtscursor und statische Cursor unterstützen. Durch das Verwenden von API-Servercursorn kann der Treiber ebenfalls keysetgesteuerte und dynamische Cursor unterstützen. SQL Server unterstützt zudem die vollständige Palette der Cursorparallelitätsattribute ausschließlich über die Servercursor. Die von Clientcursorn unterstützte Funktionalität ist begrenzt.
  • Positionierte Aktualisierungen mit höherer Genauigkeit
    Servercursor unterstützen positionierte Operationen, wie z. B. die SQLSetPos-Funktion von ODBC oder die UPDATE- und DELETE-Anweisungen, mit der WHERE CURRENT OF-Klausel. Clientcursor hingegen simulieren positionierte Cursoraktualisierungen durch Generieren einer UPDATE-Anweisung von Transact-SQL, bei der eine Suchbedingung in der WHERE-Klausel angegeben wird. Dies führt zu unbeabsichtigten Aktualisierungen, wenn mehrere Zeilen mit den Bedingungen der WHERE-Klausel der UPDATE-Anweisung übereinstimmen.
  • Speicherauslastung
    Beim Verwenden von Servercursorn ist es nicht notwendig, dass der Client große Datenmengen zwischenspeichert oder Informationen zur Cursorposition verwaltet, da der Server diese Aufgaben übernimmt.
  • Mehrere aktive Anweisungen
    Beim Verwenden von Servercursorn bleiben zwischen den Cursorvorgängen keine Ergebnisse für die Verbindung offen. Dadurch können mehrere auf Cursorn basierende Anweisungen gleichzeitig aktiv sein.

Die Operation bei allen Servercursorn, mit Ausnahme von statischen Cursorn oder Insensitivcursorn, hängt vom Schema den zugrunde liegenden Tabellen ab. Schemaänderungen in diesen Tabellen führen nach dem Deklarieren eines Cursors zu einem Fehler bei allen nachfolgenden Operationen für diesen Cursor.