Freigeben über


Cursor

Vorgänge in einer relationalen Datenbank beziehen sich immer auf eine vollständige Gruppe von Zeilen. Beispielsweise besteht der Zeilensatz, der von einer SELECT-Anweisung zurückgegeben wird, aus allen Zeilen, die die Bedingungen der WHERE-Klausel der Anweisung erfüllen. Diese vollständige Gruppe von Zeilen, die von der Anweisung zurückgegeben wird, wird als Resultset bezeichnet. Anwendungen, vor allem interaktive Onlineanwendungen, sind nicht immer effektiv, wenn das gesamte Resultset als eine Einheit bearbeitet wird. Diese Anwendungen benötigen einen Mechanismus, um jeweils eine Zeile oder einen kleinen Zeilenblock zu bearbeiten. Cursor sind eine Erweiterung zu Resultsets und stellen diesen Mechanismus bereit.

Cursor erweitern die Verarbeitung von Ergebnissen folgendermaßen:

  • Ermöglichen der Positionierung an bestimmten Zeilen des Resultsets.

  • Abrufen einer Zeile oder eines ZeilenBlocks von der aktuellen Position im Resultset.

  • Unterstützen von Datenänderungen in den Zeilen an der aktuellen Position im Resultset.

  • Unterstützen von unterschiedlichen Sichtbarkeitsebenen bei Änderungen, die von anderen Benutzern an den Datenbankdaten, die im Resultset dargestellt werden, ausgeführt wurden.

  • Bereitstellen des Zugriffs auf Daten in einem Resultset für Transact-SQL-Anweisungen in Skripts, gespeicherte Prozeduren und Trigger.

Konzepte

Cursorimplementierungen
SQL Server unterstützt drei Cursor-Implementierungen.

Transact-SQL Cursors
Basieren auf der DECLARE CURSOR-Syntax und werden hauptsächlich in Transact-SQL-Skripts, gespeicherten Prozeduren und Triggern verwendet. Transact-SQL-Cursor werden auf dem Server implementiert und mithilfe von Transact-SQL-Anweisungen verwaltet, die vom Client an den Server gesendet werden. Sie können auch in Batches, gespeicherten Prozeduren oder Triggern enthalten sein.

Application Programming Interface (API)-Servercursor
Diese 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 Server Native Client OLE DB-Anbieter oder der ODBC-Treiber die Anforderung an den Server, damit Maßnahmen für den API-Servercursor ergriffen werden.

Clientcursors
Werden intern vom SQL Server Native Client ODBC-Treiber und von 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 Server Native Client ODBC-Treiber oder die ADO-DLL die Cursoroperation auf den im Client zwischengespeicherten Resultsetzeilen aus.

Cursortypen
Vorwärtscursor
Ein Vorwärtscursor unterstützt keine Bildläufe, sondern ausschließlich das serielle Abrufen von Zeilen vom Anfang bis zum Ende des Cursors. Die Zeilen werden erst dann aus der Datenbank abgerufen, wenn der Abrufvorgang ausgeführt wird. Die Auswirkungen aller INSERT-, UPDATE- und DELETE-Anweisungen, die der aktuelle Benutzer ausführt oder für die von anderen Benutzern ein Commit ausgeführt wurde und die sich auf Zeilen im Resultset auswirken, werden dann sichtbar, wenn die Zeilen aus dem Cursor abgerufen werden.

Da mit dem Cursor kein Bildlauf rückwärts durchgeführt werden kann, sind die meisten Änderungen, die an Zeilen in der Datenbank vorgenommen wurden, nachdem die jeweilige Zeile abgerufen wurde, über den Cursor nicht sichtbar. In Fällen, in denen ein Wert, der zum Ermitteln der Zeilenposition im Resultset verwendet wird, geändert wird, z. B. durch Aktualisieren einer von einem gruppierten Index abgedeckten Spalte, ist der geänderte Wert über den Cursor sichtbar.

Obwohl die Datenbank-API-Cursormodelle einen Vorwärtscursor als einen eindeutigen Cursortyp betrachten, ist SQL Server nicht der Fall. SQL Server betrachtet sowohl die Vorwärts- als auch Bildlauffunktion als Optionen, die für statische, Keyset-gesteuerte und dynamische Cursor übernommen werden können. Transact-SQL-Cursor unterstützen statische Vorwärtscursor sowie Keyset-gesteuerte und dynamische Cursor. Die Datenbank-API-Cursormodelle gehen davon aus, dass statische, keysetgesteuerte und dynamische Cursor immer bildlauffähig sind. Wenn ein Datenbank-API-Cursor-Attribut oder eine Eigenschaft auf „Forward-only“ gesetzt ist, implementiert SQL Server dies als einen dynamischen Cursor, der nur vorwärts gerichtet ist.

statischen
Das vollständige Resultset eines statischen Cursors wird in tempdb erstellt, wenn der Cursor geöffnet wird. Ein statischer Cursor zeigt das Resultset immer so an, wie es zur Verfügung stand, als der Cursor geöffnet wurde. Statische Cursor erkennen wenige oder keine Änderungen, beanspruchen beim Durchführen eines Bildlaufs jedoch relativ wenig Ressourcen.

Der Cursor spiegelt jedoch keinerlei Änderungen wider, die in der Datenbank ausgeführt wurden und die sich entweder auf die Mitgliedschaft des Resultsets oder auf Änderungen an den Werten in den Spalten der Zeilen beziehen, aus denen das Resultset besteht. Ein statischer Cursor zeigt neue Zeilen, die nach dem Öffnen des Cursors in die Datenbank eingefügt wurden, nicht an, selbst wenn sie die Suchbedingungen der SELECT-Anweisung des Cursors erfüllen. Wenn Zeilen, aus denen sich das Resultset zusammensetzt, von anderen Benutzern aktualisiert werden, werden die neuen Datenwerte im statischen Cursor nicht angezeigt. Der statische Cursor zeigt Zeilen an, die nach dem Öffnen des Cursors aus der Datenbank entfernt wurden. Die Operationen UPDATE, INSERT oder DELETE werden in einem statischen Cursor nicht widergespiegelt (es sei denn, der Cursor wird geschlossen und wieder geöffnet). Selbst Änderungen, die mithilfe derselben Verbindung, die den Cursor öffnete, durchgeführt wurden, sind nicht enthalten.

SQL Server Statische Cursor sind immer schreibgeschützt.

Da der Resultset eines statischen Cursors in einer Arbeitstabelle in tempdb gespeichert ist, kann die Größe der Zeilen im Resultset die maximale Zeilengröße für eine SQL Server-Tabelle nicht überschreiten.

Transact-SQL verwendet den Begriff insensitive für statische Cursors. Einige Datenbank-APIs bezeichnen sie als Snapshot-Cursor.

Keyset
Die Mitgliedschaft und Reihenfolge der Zeilen in einem keysetgesteuerten Cursor werden beim Öffnen des Cursors festgelegt. Keysetgesteuerte Cursor werden von einer Reihe von eindeutigen Bezeichnern (Schlüssel) gesteuert, die als das Keyset bezeichnet werden. Die Schlüssel werden anhand einer Reihe von Spalten erstellt, die die Zeilen im Resultset eindeutig identifizieren. Das Keyset ist die Menge der Schlüsselwerte aus allen Zeilen, die zum Zeitpunkt des Öffnens des Cursors die Kriterien der SELECT-Anweisung erfüllten. Das Keyset eines keysetgesteuerten Cursors wird in tempdb erstellt, wenn der Cursor geöffnet wird.

Dynamisch
Dynamische Cursor sind das Gegenteil von statischen Cursorn. Dynamische Cursor spiegeln alle Änderungen an den Zeilen in den Resultsets beim Durchführen eines Bildlaufs durch den Cursor wider. Die Datenwerte, Reihenfolge und Mitgliedschaft der Zeilen im Resultset können sich bei jedem Abrufvorgang ändern. Jede UPDATE-, INSERT- und DELETE-Anweisung, die von einem Benutzer ausgeführt wurde, ist über den Cursor sichtbar. Updates werden sofort angezeigt, wenn sie über den Cursor mithilfe einer API-Funktion wie SQLSetPos oder der Transact-SQL WHERE CURRENT OF-Klausel vorgenommen werden. Updates, die außerhalb des Cursors ausgeführt werden, sind nur dann sichtbar, wenn ein Commit für sie ausgeführt wurde, es sei denn, die Transaktionsisolationsstufe des Cursors wurde so festgelegt, dass ein Commit vor dem Lesevorgang nicht ausgeführt sein muss. Für dynamische Cursorpläne werden nie räumliche Indizes verwendet.

Anfordern eines Cursors

SQL Server unterstützt zwei Methoden zum Anfordern eines Cursors:

  • Transact-SQL

    Die Transact-SQL-Sprache unterstützt eine Syntax für das Verwenden von Cursorn, die sich an der Syntax von ISO-Cursorn orientiert.

  • Cursorfunktionen über Datenbank-APIs (Application Programming Interface, Schnittstelle für Anwendungsprogrammierung)

    SQL Server unterstützt die Cursorfunktionen der folgenden Datenbank-APIs:

    • ADO (Microsoft ActiveX Data Objects)

    • OLE DB

    • ODBC (Open Database Connectivity)

Eine Anwendung sollte niemals diese zwei Methoden für das Anfordern eines Cursors mischen. Eine Anwendung, die die API zum Angeben von Cursorverhalten verwendet hat, sollte dann keine Transact-SQL DECLARE CURSOR-Anweisung ausführen, um auch einen Transact-SQL-Cursor anzufordern. Die Anwendung sollte nur dann DECLARE CURSOR ausführen, wenn alle API-Cursorattribute auf die entsprechenden Standardeinstellungen zurückgesetzt wurden.

Wenn weder ein Transact-SQL- noch API-Cursor angefordert wurde, gibt SQL Server standardmäßig ein vollständiges Resultset zurück, das als Standardergebnissatz bezeichnet wird, an die Anwendung zurückzugeben.

Cursorprozesse

Transact-SQL-Cursor und API-Cursor verfügen über eine unterschiedliche Syntax. Es wird jedoch der folgende allgemeine Prozess bei allen SQL Server-Cursorn verwendet:

  1. Verbinden Sie einen Cursor mit dem Resultset einer Transact-SQL-Anweisung, und definieren Sie die Eigenschaften des Cursors, wie z. B., ob die Zeilen im Cursor aktualisiert werden können.

  2. Führen Sie die Transact-SQL-Anweisung aus, um den Cursor aufzufüllen.

  3. Rufen Sie die Zeilen in den Cursor ab, die Sie anzeigen möchten. Der Vorgang, durch die eine Zeile oder ein Zeilenblock von einem Cursor abgerufen wird, wird als Abrufvorgang bezeichnet. Wird eine Folge von Abrufvorgängen vorwärts oder rückwärts ausgeführt, wird dies als Durchführen eines Bildlaufs bezeichnet.

  4. Führen Sie optional Änderungsvorgänge (Aktualisieren oder Löschen) in der Zeile an der aktuellen Position im Cursor aus.

  5. Schließen Sie den Cursor.

Cursorverhalten, wie Cursor implementiert werden

Weitere Informationen

DECLARE CURSOR (Transact-SQL)
Cursor (Transact-SQL)
Cursorfunktionen (Transact-SQL)
Gespeicherte Cursorprozeduren (Transact-SQL)