Cursor (SQL Server)

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance

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. Dieser vollständige Satz von Zeilen, die von der Anweisung zurückgegeben werden, wird als Resultset bezeichnet. Anwendungen, insbesondere interaktive Online-Anwendungen, können nicht immer effektiv mit dem gesamten Resultset als Einheit arbeiten. 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 von Transact-SQL-Anweisungen in Skripts, gespeicherten Prozeduren und löst den Zugriff auf die Daten in einem Resultset aus.

Hinweise

Wenn es in einigen Szenarien einen Primärschlüssel in einer Tabelle gibt, kann eine WHILE Schleife anstelle eines Cursors verwendet werden, ohne dass der Aufwand für einen Cursor entsteht.

Es gibt jedoch Szenarien, in denen Cursor nicht nur unvermeidbar sind, sondern tatsächlich benötigt werden. Wenn dies der Fall ist, wenn es keine Notwendigkeit gibt, Tabellen basierend auf dem Cursor zu aktualisieren, verwenden Sie FirehoseCursor , was bedeutet, dass schnelle und schreibgeschützte Cursor.

Cursorimplementierungen

SQL Server unterstützt drei Cursorimplementierungen.

Cursorimplementierung Beschreibung
Transact-SQL-Cursor Transact-SQL-Cursor basieren auf der DECLARE CURSOR Syntax und werden Standard in Transact-SQL-Skripts, gespeicherten Prozeduren und Triggern verwendet. Transact-SQL-Cursor werden auf dem Server implementiert und 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.
Api-Servercursor (Application Programming Interface) API-Cursor unterstützen die API-Cursorfunktionen in OLE DB und ODBC. API-Servercursor werden auf dem Server implementiert. Jedes Mal, wenn eine Clientanwendung eine API-Cursorfunktion aufruft, überträgt der OLE DB-Anbieter des SQL Server Native Client oder ODBC-Treiber die Anforderung an den Server zur Aktion gegen den API-Servercursor.
Clientcursor Clientcursor 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. Jedes Mal, wenn eine Clientanwendung eine API-Cursorfunktion aufruft, führt der SQL Server Native Client ODBC-Treiber oder die ADO-DLL den Cursorvorgang für die Resultsetzeilen aus, die auf dem Client zwischengespeichert sind.

Cursortyp

SQL Server unterstützt vier Cursortypen.

Cursor können Arbeitstabellen verwenden tempdb . Genau wie Aggregations- oder Sortiervorgänge, die überlaufen, entstehen diese E/A-Kosten und stellen einen potenziellen Leistungsengpässe dar. STATIC-Cursor verwenden von Beginn an Arbeitstabellen. Weitere Informationen finden Sie im Abschnitt "Arbeitstabellen" im Leitfaden zur Abfrageverarbeitungsarchitektur.

Vorwärtscursor

Ein Vorwärtscursor wird als FORWARD_ONLY "Vorwärtscursor" angegeben und READ_ONLY unterstützt keinen Bildlauf. Diese Cursor werden auch Firehosecursor genannt und unterstützen nur das serielle Abrufen der Zeilen vom Anfang bis zum Ende des Cursors. Die Zeilen werden erst aus der Datenbank abgerufen, wenn sie abgerufen werden. 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 der Cursor nicht rückwärts gescrollt werden kann, sind die meisten Änderungen, die an Zeilen in der Datenbank vorgenommen wurden, nachdem die Zeile abgerufen wurde, nicht durch den Cursor 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 Vorwärts- als auch Bildlauf als Optionen, die auf statische, keysetgesteuerte und dynamische Cursor angewendet werden können. Transact-SQL-Cursor unterstützen vorwärtsgerichtete statische, keysetgesteuerte 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" festgelegt ist, implementiert SQL Server dies als vorwärtsgeschützten dynamischen Cursor.

Statisch

Das vollständige Resultset eines statischen Cursors wird beim Öffnen des Cursors integriert tempdb . 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 enthält keine Änderungen an der Datenbank, die sich auf die Mitgliedschaft des Resultsets auswirken, oder Änderungen an den Werten in den Spalten der Zeilen, aus denen das Resultset besteht. Ein statischer Cursor zeigt keine neuen Zeilen an, die nach dem Öffnen des Cursors in die Datenbank eingefügt wurden, auch wenn sie den Suchbedingungen der Cursor-Anweisung SELECT entsprechen. Wenn Zeilen, die das Resultset bilden, von anderen Benutzern aktualisiert werden, werden die neuen Datenwerte nicht im statischen Cursor 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.

Hinweis

Statische SQL Server-Cursor sind immer schreibgeschützt.

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

Weitere Informationen finden Sie im Abschnitt "Arbeitstabellen" im Leitfaden zur Abfrageverarbeitungsarchitektur. Weitere Informationen zur maximalen Zeilengröße finden Sie unter maximale Kapazitätsspezifikationen für SQL Server.

Transact-SQL verwendet den Begriff "Insensitive " für statische Cursor. Einige Datenbank-APIs identifizieren sie als Momentaufnahme Cursor.

Keyset

Die Mitgliedschaft und Reihenfolge der Zeilen in einem keysetgesteuerten Cursor werden beim Öffnen des Cursors festgelegt. Keysetgesteuerte Cursor werden durch eine Reihe eindeutiger Bezeichner oder Schlüssel gesteuert, die als 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 für einen keysetgesteuerten Cursor wird beim Öffnen des Cursors integriert tempdb .

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 z. B. oder der Transact-SQL-Klausel WHERE CURRENT OF vorgenommen werden. Aktualisierungen, die außerhalb des Cursors vorgenommen wurden, werden erst angezeigt, wenn sie zugesichert wurden, es sei denn, die Cursortransaktionsisolationsstufe ist auf "Nicht ausgelassen" festgelegt. Weitere Informationen zu Isolationsstufen finden Sie unter SET TRANSACTION ISOLATION LEVEL (Transact-SQL).For more information on isolation levels, see SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

Hinweis

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 die Verwendung von Cursorn, die nach der ISO-Cursorsyntax modelliert wurden.

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

    SQL Server unterstützt die Cursorfunktionalität dieser Datenbank-APIs:

    • ADO (Microsoft ActiveX Data-Objekt)

    • 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, sollte dann keine Transact-SQL-Anweisung DECLARE CURSOR ausführen, um auch einen Transact-SQL-Cursor anzufordern. Eine Anwendung sollte nur ausgeführt werden DECLARE CURSOR , wenn alle API-Cursorattribute wieder auf ihre Standardwerte festgelegt werden.

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

Cursorprozess

Transact-SQL-Cursor und API-Cursor weisen unterschiedliche Syntax auf, der folgende allgemeine Prozess wird jedoch mit allen SQL Server-Cursorn verwendet:

  1. Ordnen Sie dem Resultset einer Transact-SQL-Anweisung einen Cursor zu, und definieren Sie Die Merkmale des Cursors, 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.