CursorCursors

GILT FÜR: jaSQL ServerjaAzure SQL-DatenbankneinAzure SQL Data Warehouse neinParallel Data WarehouseAPPLIES TO: yesSQL Server yesAzure SQL Database noAzure SQL Data Warehouse noParallel Data Warehouse

Vorgänge in einer relationalen Datenbank beziehen sich immer auf eine vollständige Gruppe von Zeilen.Operations in a relational database act on a complete set of rows. 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.For example, the set of rows returned by a SELECT statement consists of all the rows that satisfy the conditions in the WHERE clause of the statement. Diese vollständige Gruppe von Zeilen, die von der Anweisung zurückgegeben wird, wird als Resultset bezeichnet.This complete set of rows returned by the statement is known as the result set. Anwendungen, vor allem interaktive Onlineanwendungen, sind nicht immer effektiv, wenn das gesamte Resultset als eine Einheit bearbeitet wird.Applications, especially interactive online applications, cannot always work effectively with the entire result set as a unit. Diese Anwendungen benötigen einen Mechanismus, um jeweils eine Zeile oder einen kleinen Zeilenblock zu bearbeiten.These applications need a mechanism to work with one row or a small block of rows at a time. Cursor sind eine Erweiterung zu Resultsets und stellen diesen Mechanismus bereit.Cursors are an extension to result sets that provide that mechanism.

Cursor erweitern die Verarbeitung von Ergebnissen folgendermaßen:Cursors extend result processing by:

  • Ermöglichen der Positionierung an bestimmten Zeilen des Resultsets.Allowing positioning at specific rows of the result set.

  • Abrufen einer Zeile oder eines ZeilenBlocks von der aktuellen Position im Resultset.Retrieving one row or block of rows from the current position in the result set.

  • Unterstützen von Datenänderungen in den Zeilen an der aktuellen Position im Resultset.Supporting data modifications to the rows at the current position in the result set.

  • Unterstützen von unterschiedlichen Sichtbarkeitsebenen bei Änderungen, die von anderen Benutzern an den Datenbankdaten, die im Resultset dargestellt werden, ausgeführt wurden.Supporting different levels of visibility to changes made by other users to the database data that is presented in the result set.

  • Bereitstellen des Zugriffs auf Daten in einem Resultset für Transact-SQLTransact-SQL -Anweisungen in Skripts, gespeicherte Prozeduren und Trigger.Providing Transact-SQLTransact-SQL statements in scripts, stored procedures, and triggers access to the data in a result set.

Tipp

In einigen Szenarien kann bei Vorhandensein eines Primärschlüssels für eine Tabelle eine WHILE-Schleife anstelle eines Cursors verwendet werden, ohne zum Mehraufwand eines Cursors beizutragen.In some scenarios, if there is a primary key on a table, a WHILE loop can be used instead of a cursor, without incurring in the overhead of a cursor. Es gibt jedoch Szenarien, in denen Cursor nicht nur unvermeidbar sind, sondern tatsächlich benötigt werden.However, there are scenarios where cursors are not only unavoidable, they are actually needed. Wenn das der Fall ist und keine Aktualisierung von Tabellen basierend auf dem Cursor erforderlich ist, verwenden Sie Firehosecursor, d. h. Vorwärts- und schreibgeschützte Cursor.When that is the case, if there is no requirement to update tables based on the cursor, then use firehose cursors, meaning fast-forward and read-only cursors.

CursorimplementierungenCursor Implementations

SQL ServerSQL Server unterstützt drei Cursorimplementierungen.supports three cursor implementations.

Transact-SQL-CursorTransact-SQL cursors

Transact-SQLTransact-SQL-Cursor basieren auf der DECLARE CURSOR-Syntax und werden hauptsächlich in Transact-SQLTransact-SQL-Skripts, gespeicherten Prozeduren und Triggern verwendet.cursors are based on the DECLARE CURSOR syntax and used mainly in Transact-SQLTransact-SQL scripts, stored procedures, and triggers. Transact-SQLTransact-SQL -Cursor werden auf dem Server implementiert und mithilfe von Transact-SQLTransact-SQL -Anweisungen verwaltet, die vom Client an den Server gesendet werden.cursors are implemented on the server and are managed by Transact-SQLTransact-SQL statements sent from the client to the server. Sie können auch in Batches, gespeicherten Prozeduren oder Triggern enthalten sein.They may also be contained in batches, stored procedures, or triggers.

API-Servercursor (Application Programming Interface, Schnittstelle für Anwendungsprogrammierung)Application programming interface (API) server cursors

API-Cursor unterstützen die API-Cursorfunktionen in OLE DB und ODBC.API cursors support the API cursor functions in OLE DB and ODBC. API-Servercursor werden auf dem Server implementiert.API server cursors are implemented on the server. Wenn eine Clientanwendung eine API-Cursorfunktion aufruft, überträgt der SQL ServerSQL 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.Each time a client application calls an API cursor function, the SQL ServerSQL Server Native Client OLE DB provider or ODBC driver transmits the request to the server for action against the API server cursor.

ClientcursorClient cursors

Clientcursor werden intern vom SQL ServerSQL Server Native Client-ODBC-Treiber und der DLL implementiert, die die ADO-API implementiert.Client cursors are implemented internally by the SQL ServerSQL Server Native Client ODBC driver and by the DLL that implements the ADO API. Clientcursor werden durch Zwischenspeichern aller Resultsetzeilen auf dem Client implementiert.Client cursors are implemented by caching all the result set rows on the client. Wenn eine Clientanwendung eine API-Cursorfunktion aufruft, führen der SQL ServerSQL Server Native ODBC-Treiber oder die ADO-DLL die Cursoroperation auf den im Client zwischengespeicherten Resultsetzeilen aus.Each time a client application calls an API cursor function, the SQL ServerSQL Server Native Client ODBC driver or the ADO DLL performs the cursor operation on the result set rows cached on the client.

CursortypenType of Cursors

SQL ServerSQL Server unterstützt vier Cursortypen.supports four cursor types.

Hinweis

Cursor können tempdb Arbeitstabellen nutzen.Cursors may leverage tempdb worktables. Wie Aggregations- oder Sortiervorgänge, die überlaufen, können diese zur E/A beitragen und stellen einen potenziellen Leistungsengpass dar.Just like aggregation or sort operations that spill, these incur in I/O, and are a potential performance bottleneck. STATIC-Cursor verwenden von Beginn an Arbeitstabellen.STATIC cursors use worktables from its inception. Weitere Informationen finden Sie unter „Arbeitstabellen“ im Handbuch zur Architektur der Abfrageverarbeitung.For more information, see worktables in the Query Processing Architecture Guide.

VorwärtscursorForward-only

Ein Vorwärtscursor wird als FORWARD_ONLY und READ_ONLY angegeben und unterstützt kein Scrollen.A forward-only cursor is specified as FORWARD_ONLY and READ_ONLY and does not support scrolling. Diese Cursor werden auch Firehosecursor genannt und unterstützen nur das serielle Abrufen der Zeilen vom Anfang bis zum Ende des Cursors.These are also called firehose cursors and support only fetching the rows serially from the start to the end of the cursor. Die Zeilen werden erst dann aus der Datenbank abgerufen, wenn der Abrufvorgang ausgeführt wird.The rows are not retrieved from the database until they are fetched. 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.The effects of all INSERT, UPDATE, and DELETE statements made by the current user or committed by other users that affect rows in the result set are visible as the rows are fetched from the cursor.

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.Because the cursor cannot be scrolled backward, most changes made to rows in the database after the row was fetched are not visible through the cursor. 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.In cases where a value used to determine the location of the row within the result set is modified, such as updating a column covered by a clustered index, the modified value is visible through the cursor.

Obwohl die Datenbank-API-Cursormodelle einen Vorwärtscursor als unterschiedlichen Cursortyp betrachten, gilt dies nicht für SQL ServerSQL Server .Although the database API cursor models consider a forward-only cursor to be a distinct type of cursor, SQL ServerSQL Server does not. SQL ServerSQL Server betrachtet sowohl die Vorwärts- als auch Bildlauffunktion als Optionen, die für statische, keysetgesteuerte und dynamische Cursor übernommen werden können.considers both forward-only and scroll as options that can be applied to static, keyset-driven, and dynamic cursors. Transact-SQLTransact-SQL -Cursor unterstützen statische Vorwärtscursor sowie keysetgesteuerte und dynamische Cursor.cursors support forward-only static, keyset-driven, and dynamic cursors. Die Datenbank-API-Cursormodelle gehen davon aus, dass statische, keysetgesteuerte und dynamische Cursor immer bildlauffähig sind.The database API cursor models assume that static, keyset-driven, and dynamic cursors are always scrollable. Wenn das Cursorattribut oder die Cursoreigenschaft einer Datenbank-API auf FORWARD_ONLY festgelegt ist, wird dies von SQL ServerSQL Server als dynamischer Vorwärtscursor implementiert.When a database API cursor attribute or property is set to forward-only, SQL ServerSQL Server implements this as a forward-only dynamic cursor.

STATIC-CursorStatic

Das vollständige Resultset eines statischen Cursors wird in tempdb erstellt, wenn der Cursor geöffnet wird.The complete result set of a static cursor is built in tempdb when the cursor is opened. Ein statischer Cursor zeigt das Resultset immer so an, wie es zur Verfügung stand, als der Cursor geöffnet wurde.A static cursor always displays the result set as it was when the cursor was opened. Statische Cursor erkennen wenige oder keine Änderungen, beanspruchen beim Durchführen eines Bildlaufs jedoch relativ wenig Ressourcen.Static cursors detect few or no changes, but consume relatively few resources while scrolling.

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.The cursor does not reflect any changes made in the database that affect either the membership of the result set or changes to the values in the columns of the rows that make up the result set. 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.A static cursor does not display new rows inserted in the database after the cursor was opened, even if they match the search conditions of the cursor SELECT statement. Wenn Zeilen, aus denen sich das Resultset zusammensetzt, von anderen Benutzern aktualisiert werden, werden die neuen Datenwerte im statischen Cursor nicht angezeigt.If rows making up the result set are updated by other users, the new data values are not displayed in the static cursor. Der statische Cursor zeigt Zeilen an, die nach dem Öffnen des Cursors aus der Datenbank entfernt wurden.The static cursor displays rows deleted from the database after the cursor was opened. 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.No UPDATE, INSERT, or DELETE operations are reflected in a static cursor (unless the cursor is closed and reopened), not even modifications made using the same connection that opened the cursor.

Hinweis

SQL ServerSQL Server : Statische Cursor sind immer schreibgeschützt.static cursors are always read-only.

Hinweis

Da das Resultset eines statischen Cursors in einer Arbeitstabelle in tempdb gespeichert wird, darf die Größe der Zeilen im Resultset die maximale Zeilengröße einer SQL ServerSQL Server -Tabelle nicht überschreiten.Because the result set of a static cursor is stored in a worktable in tempdb, the size of the rows in the result set cannot exceed the maximum row size for a SQL ServerSQL Server table.
Weitere Informationen finden Sie unter „Arbeitstabellen“ im Handbuch zur Architektur der Abfrageverarbeitung.For more information, see worktables in the Query Processing Architecture Guide. Weitere Informationen zur maximalen Zeilengröße finden Sie unter Spezifikationen der maximalen Kapazität für SQL Server.For more information on max row size, see Maximum Capacity Specifications for SQL Server.

Transact-SQLTransact-SQL werden statische Cursor als Insensitivcursor bezeichnet, also Cursor, bei denen keine Unterscheidung gemacht wird.uses the term insensitive for static cursors. Von einigen Datenbank-Anwendungsprogrammierschnittstellen (APIs, Application Programming Interfaces) werden sie als Momentaufnahmecursor bezeichnet.Some database APIs identify them as snapshot cursors.

KeysetKeyset

Die Mitgliedschaft und Reihenfolge der Zeilen in einem keysetgesteuerten Cursor werden beim Öffnen des Cursors festgelegt.The membership and order of rows in a keyset-driven cursor are fixed when the cursor is opened. Keysetgesteuerte Cursor werden von einer Reihe von eindeutigen Bezeichnern (Schlüssel) gesteuert, die als das Keyset bezeichnet werden.Keyset-driven cursors are controlled by a set of unique identifiers, keys, known as the keyset. Die Schlüssel werden anhand einer Reihe von Spalten erstellt, die die Zeilen im Resultset eindeutig identifizieren.The keys are built from a set of columns that uniquely identify the rows in the result set. 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.The keyset is the set of the key values from all the rows that qualified for the SELECT statement at the time the cursor was opened. Das Keyset eines keysetgesteuerten Cursors wird in tempdb erstellt, wenn der Cursor geöffnet wird.The keyset for a keyset-driven cursor is built in tempdb when the cursor is opened.

DynamicDynamic

Dynamische Cursor sind das Gegenteil von statischen Cursorn.Dynamic cursors are the opposite of static cursors. Dynamische Cursor spiegeln alle Änderungen an den Zeilen in den Resultsets beim Durchführen eines Bildlaufs durch den Cursor wider.Dynamic cursors reflect all changes made to the rows in their result set when scrolling through the cursor. Die Datenwerte, Reihenfolge und Mitgliedschaft der Zeilen im Resultset können sich bei jedem Abrufvorgang ändern.The data values, order, and membership of the rows in the result set can change on each fetch. Jede UPDATE-, INSERT- und DELETE-Anweisung, die von einem Benutzer ausgeführt wurde, ist über den Cursor sichtbar.All UPDATE, INSERT, and DELETE statements made by all users are visible through the cursor. Updates sind sofort sichtbar, wenn sie über den Cursor mithilfe einer API-Funktion, wie z.B. SQLSetPos, oder der WHERE CURRENT OF-Klausel von Transact-SQLTransact-SQL ausgeführt wurden.Updates are visible immediately if they are made through the cursor using either an API function such as SQLSetPos or the Transact-SQLTransact-SQL WHERE CURRENT OF clause. 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.Updates made outside the cursor are not visible until they are committed, unless the cursor transaction isolation level is set to read uncommitted. 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.Dynamic cursor plans never use spatial indexes.

Anfordern eines CursorsRequesting a Cursor

SQL ServerSQL Server unterstützt zwei Methoden zum Anfordern eines Cursors:supports two methods for requesting a cursor:

  • Transact-SQLTransact-SQL

    Die Transact-SQLTransact-SQL -Sprache unterstützt eine Syntax für das Verwenden von Cursorn, die sich an der Syntax von ISO-Cursorn orientiert.The Transact-SQLTransact-SQL language supports a syntax for using cursors modeled after the ISO cursor syntax.

  • Cursorfunktionen über Datenbank-APIs (Application Programming Interface, Schnittstelle für Anwendungsprogrammierung)Database application programming interface (API) cursor functions

    SQL ServerSQL Server unterstützt die Cursorfunktionen der folgenden Datenbank-APIs:supports the cursor functionality of these database APIs:

    • ADO ( MicrosoftMicrosoft ActiveX-Datenobjekt)ADO ( MicrosoftMicrosoft ActiveX Data Object)

    • OLE DBOLE DB

    • ODBC (Open Database Connectivity)ODBC (Open Database Connectivity)

Eine Anwendung sollte niemals diese zwei Methoden für das Anfordern eines Cursors mischen.An application should never mix these two methods of requesting a cursor. Eine Anwendung, die die API zum Angeben des Cursorverhaltens verwendet hat, sollte nicht anschließend eine DECLARE CURSOR-Anweisung von Transact-SQLTransact-SQL ausführen, um auch einen Transact-SQLTransact-SQL -Cursor anzufordern.An application that has used the API to specify cursor behaviors should not then execute a Transact-SQLTransact-SQL DECLARE CURSOR statement to also request a Transact-SQLTransact-SQL cursor. Die Anwendung sollte nur dann DECLARE CURSOR ausführen, wenn alle API-Cursorattribute auf die entsprechenden Standardeinstellungen zurückgesetzt wurden.An application should only execute DECLARE CURSOR if it has set all the API cursor attributes back to their defaults.

Wenn weder ein Transact-SQLTransact-SQL -Cursor noch ein API-Cursor angefordert wurde, gibt SQL ServerSQL Server standardmäßig ein vollständiges Resultset, das als Standardresultset bezeichnet wird, an die Anwendung zurück.If neither a Transact-SQLTransact-SQL nor API cursor has been requested, SQL ServerSQL Server defaults to returning a complete result set, known as a default result set, to the application.

CursorprozesseCursor Process

Transact-SQLTransact-SQL -Cursor und API-Cursor verfügen über eine unterschiedliche Syntax. Es wird jedoch der folgende allgemeine Prozess bei allen SQL ServerSQL Server -Cursorn verwendet:cursors and API cursors have different syntax, but the following general process is used with all SQL ServerSQL Server cursors:

  1. Verbinden Sie einen Cursor mit dem Resultset einer Transact-SQLTransact-SQL -Anweisung, und definieren Sie die Eigenschaften des Cursors (z. B., ob die Zeilen im Cursor aktualisiert werden können).Associate a cursor with the result set of a Transact-SQLTransact-SQL statement, and define characteristics of the cursor, such as whether the rows in the cursor can be updated.

  2. Führen Sie die Transact-SQLTransact-SQL -Anweisung aus, um den Cursor aufzufüllen.Execute the Transact-SQLTransact-SQL statement to populate the cursor.

  3. Rufen Sie die Zeilen in den Cursor ab, die Sie anzeigen möchten.Retrieve the rows in the cursor you want to see. Der Vorgang, durch die eine Zeile oder ein Zeilenblock von einem Cursor abgerufen wird, wird als Abrufvorgang bezeichnet.The operation to retrieve one row or one block of rows from a cursor is called a fetch. Wird eine Folge von Abrufvorgängen vorwärts oder rückwärts ausgeführt, wird dies als Durchführen eines Bildlaufs bezeichnet.Performing a series of fetches to retrieve rows in either a forward or backward direction is called scrolling.

  4. Führen Sie optional Änderungsvorgänge (Aktualisieren oder Löschen) in der Zeile an der aktuellen Position im Cursor aus.Optionally, perform modification operations (update or delete) on the row at the current position in the cursor.

  5. Schließen Sie den Cursor.Close the cursor.

Cursorverhalten Cursor Behaviors
Implementieren von CursornHow Cursors Are Implemented

Weitere Informationen finden Sie unterSee Also

DECLARE CURSOR (Transact-SQL) DECLARE CURSOR (Transact-SQL)
Cursors (Transact-SQL) Cursors (Transact-SQL)
Cursorfunktionen (Transact-SQL) Cursor Functions (Transact-SQL)
Gespeicherte Cursorprozeduren (Transact-SQL) Cursor Stored Procedures (Transact-SQL)
SET TRANSACTION ISOLATION LEVEL (Transact-SQL)SET TRANSACTION ISOLATION LEVEL (Transact-SQL)