- 14.03.2017
- 13 Minuten zum Lesen
-
- c
- r
- i
- M
- m
-
+6
Gilt für: SQL Server (alle unterstützten Versionen) ) Azure SQL-Datenbank
Definiert die Attribute eines Transact-SQL-Servercursors, z. B. das Bildlaufverhalten und die Abfrage, mit der die Ergebnismenge erstellt wird Der Cursor arbeitet. DECLARE CURSOR
akzeptiert sowohl eine auf dem ISO-Standard basierende Syntax als auch eine Syntax, die eine Reihe von Transact-SQL-Erweiterungen verwendet.
Transact-SQL-Syntaxkonventionen
Syntax
Hinweis
Informationen zum Anzeigen der Transact-SQL-Syntax für SQL Server 2014 und frühere Versionen finden Sie in der Dokumentation zu früheren Versionen .
Argumente
Cursorname
Ist der Name des Transact-SQL-Servercursors definiert. Der Cursorname muss den Regeln für Bezeichner entsprechen.
INSENSITIVE
Definiert einen Cursor, der eine temporäre Kopie der vom Cursor zu verwendenden Daten erstellt. Alle Anforderungen an den Cursor werden aus dieser temporären Tabelle in tempdb beantwortet. Daher werden an Basistabellen vorgenommene Änderungen nicht in den Daten wiedergegeben, die von Abrufen an diesem Cursor zurückgegeben werden, und dieser Cursor erlaubt keine Änderungen. Wenn bei Verwendung der ISO-Syntax INSENSITIVE
weggelassen wird, werden festgeschriebene Löschvorgänge und Aktualisierungen der zugrunde liegenden Tabellen (von jedem Benutzer) in nachfolgenden Abrufen wiedergegeben.
SCROLL
Gibt an, dass alle Abrufoptionen (FIRST
, LAST
, PRIOR
, NEXT
, RELATIVE
, ABSOLUTE
) sind verfügbar. Wenn SCROLL
in einer ISO DECLARE CURSOR
nicht angegeben ist, wird NEXT
als einzige Abrufoption unterstützt . SCROLL
kann nicht angegeben werden, wenn auch FAST_FORWARD
angegeben ist. Wenn SCROLL
nicht angegeben ist, ist nur die Abrufoption NEXT
verfügbar und der Cursor wird FORWARD_ONLY
.
select_statement
Ist eine Standardanweisung SELECT
, die die Ergebnismenge des Cursors definiert. Die Schlüsselwörter FOR BROWSE
und INTO
sind in select_statement einer Cursordeklaration nicht zulässig.
SQL Server konvertiert das implizit Cursor auf einen anderen Typ, wenn Klauseln in select_statement mit der Funktionalität des angeforderten Cursortyps in Konflikt stehen.
NUR LESEN
Verhindert Aktualisierungen, die über diesen Cursor vorgenommen werden. Der Cursor kann nicht in einer WHERE CURRENT OF
-Klausel in einer UPDATE
– oder DELETE
-Anweisung referenziert werden. Diese Option überschreibt die Standardfunktion eines zu aktualisierenden Cursors.
Cursorname
Ist der Name des Transact-SQL-Servercursors definiert. Der Cursorname muss den Regeln für Bezeichner entsprechen.
LOKAL
Gibt an, dass der Bereich des Cursors lokal für den Stapel, die gespeicherte Prozedur oder den Trigger ist, in dem der Cursor erstellt wurde. Der Cursorname ist nur in diesem Bereich gültig. Der Cursor kann durch lokale Cursorvariablen im Stapel, in der gespeicherten Prozedur oder im Trigger oder durch einen Parameter der gespeicherten Prozedur OUTPUT
referenziert werden. Ein OUTPUT
-Parameter wird verwendet, um den lokalen Cursor an den aufrufenden Stapel, die gespeicherte Prozedur oder den Trigger zurückzugeben, der den Parameter einer Cursor-Variablen zuweisen kann, um auf den Cursor nach der gespeicherten Prozedur zu verweisen wird beendet. Der Cursor wird implizit freigegeben, wenn der Stapel, die gespeicherte Prozedur oder der Trigger beendet werden, es sei denn, der Cursor wurde in einem OUTPUT
-Parameter zurückgegeben. Wenn es in einem OUTPUT
-Parameter zurückgegeben wird, wird der Cursor freigegeben, wenn die letzte Variable, auf die verwiesen wird, freigegeben wird oder den Gültigkeitsbereich verlässt.
GLOBAL
Gibt an, dass der Bereich des Cursors für die Verbindung global ist. Der Cursorname kann in jeder von der Verbindung ausgeführten gespeicherten Prozedur oder jedem Stapel referenziert werden. Der Cursor wird nur beim Trennen implizit freigegeben.
Hinweis
Wenn weder GLOBAL
noch LOCAL
wird angegeben, der Standard wird durch die Einstellung der Standardoption für die lokale Cursor-Datenbank gesteuert.
FORWARD_ONLY
Gibt an, dass der Cursor nur vorwärts bewegt und gescrollt werden kann die erste bis letzte Reihe. FETCH NEXT
ist die einzige unterstützte Abrufoption. Alle vom aktuellen Benutzer (oder von anderen Benutzern festgeschriebenen) Anweisungen zum Einfügen, Aktualisieren und Löschen, die sich auf Zeilen in der Ergebnismenge auswirken, werden beim Abrufen der Zeilen angezeigt.Da der Cursor nicht rückwärts gescrollt werden kann, sind Änderungen, die nach dem Abrufen der Zeile an Zeilen in der Datenbank vorgenommen wurden, nicht über den Cursor sichtbar. Nur-Vorwärts-Cursor sind standardmäßig dynamisch. Dies bedeutet, dass alle Änderungen erkannt werden, wenn die aktuelle Zeile verarbeitet wird. Dies ermöglicht ein schnelleres Öffnen des Cursors und ermöglicht es der Ergebnismenge, Aktualisierungen der zugrunde liegenden Tabellen anzuzeigen. Während Nur-Vorwärts-Cursor kein Rückwärts-Scrollen unterstützen, können Anwendungen durch Schließen und erneutes Öffnen des Cursors zum Anfang der Ergebnismenge zurückkehren. Wenn FORWARD_ONLY
ohne , KEYSET
oder DYNAMIC
fungiert der Cursor als dynamischer Cursor. Wenn weder FORWARD_ONLY
noch SCROLL
angegeben ist, ist FORWARD_ONLY
die Standardeinstellung, es sei denn, die Schlüsselwörter STATIC
, KEYSET
oder DYNAMIC
werden angegeben. STATIC
, KEYSET
und DYNAMIC
Cursor verwenden standardmäßig SCROLL
. Im Gegensatz zu Datenbank-APIs wie ODBC und ADO wird FORWARD_ONLY
mit STATIC
, KEYSET
unterstützt. und DYNAMIC
Transact-SQL-Cursor.
STATIC
Gibt an, dass der Cursor die Ergebnismenge immer so anzeigt, wie sie war, als der Cursor zum ersten Mal geöffnet wurde, und macht Eine temporäre Kopie der vom Cursor zu verwendenden Daten. Alle Anfragen an den Cursor werden aus dieser temporären Tabelle in tempdb beantwortet. Daher werden Einfügungen, Aktualisierungen und Löschungen an Basistabellen nicht in den Daten wiedergegeben, die von Abrufen an diesen Cursor zurückgegeben werden, und dieser Cursor erkennt keine Änderungen an der Mitgliedschaft, Reihenfolge oder den Werten der Ergebnismenge, die nach dem Öffnen des Cursors vorgenommen wurden . Statische Cursor erkennen möglicherweise ihre eigenen Aktualisierungen, Löschungen und Einfügungen, obwohl dies nicht erforderlich ist. Angenommen, ein statischer Cursor ruft eine Zeile ab, und eine andere Anwendung aktualisiert diese Zeile. Wenn die Anwendung die Zeile vom statischen Cursor erneut abruft, bleiben die angezeigten Werte trotz der von der anderen Anwendung vorgenommenen Änderungen unverändert. Alle Arten des Bildlaufs werden unterstützt.
KEYSET
Gibt an, dass die Zugehörigkeit und Reihenfolge der Zeilen im Cursor beim Öffnen des Cursors festgelegt werden. Der Schlüsselsatz, der die Zeilen eindeutig identifiziert, ist in eine Tabelle in tempdb integriert, die als Keyset bezeichnet wird. Dieser Cursor bietet Funktionen zwischen einem statischen und einem dynamischen Cursor, um Änderungen zu erkennen. Wie ein statischer Cursor erkennt er nicht immer Änderungen an der Zugehörigkeit und Reihenfolge der Ergebnismenge. Wie ein dynamischer Cursor erkennt er Änderungen an den Werten von Zeilen in der Ergebnismenge. Keyset-gesteuerte Cursor werden durch eine Reihe eindeutiger Bezeichner (Schlüssel) gesteuert, die als Keyset bezeichnet werden. Die Schlüssel bestehen aus einer Reihe von Spalten, die die Zeilen in der Ergebnismenge eindeutig identifizieren. Das Keyset ist die Menge der Schlüsselwerte aus allen von der Abfrageanweisung zurückgegebenen Zeilen. Bei schlüsselsatzgesteuerten Cursorn wird für jede Zeile im Cursor ein Schlüssel erstellt und gespeichert und entweder auf der Client-Workstation oder auf dem Server gespeichert. Wenn Sie auf jede Zeile zugreifen, werden mit dem gespeicherten Schlüssel die aktuellen Datenwerte aus der Datenquelle abgerufen. In einem Keyset-gesteuerten Cursor wird die Mitgliedschaft in der Ergebnismenge eingefroren, wenn der Keyset vollständig ausgefüllt ist. Danach sind Ergänzungen oder Aktualisierungen, die sich auf die Mitgliedschaft auswirken, erst nach dem erneuten Öffnen Teil der Ergebnismenge. Änderungen an Datenwerten (entweder vom Keyset-Eigentümer oder von anderen Prozessen vorgenommen) werden angezeigt, wenn der Benutzer durch die Ergebnismenge blättert:
- Wenn eine Zeile gelöscht wird, gibt ein Versuch, die Zeile abzurufen, eine
@@FETCH_STATUS
von -2 zurück, da die gelöschte Zeile als Lücke in der Ergebnismenge angezeigt wird. Der Schlüssel für die Zeile ist im Keyset vorhanden, die Zeile ist jedoch nicht mehr in der Ergebnismenge vorhanden. - Einfügungen außerhalb des Cursors (durch andere Prozesse) sind nur sichtbar, wenn der Cursor geschlossen und erneut geöffnet wird. Einfügungen innerhalb des Cursors werden am Ende der Ergebnismenge angezeigt.
- Aktualisierungen von Schlüsselwerten von außerhalb des Cursors ähneln einem Löschen der alten Zeile, gefolgt von einem Einfügen der neuen Zeile. Die Zeile mit den neuen Werten ist nicht sichtbar, und Versuche, die Zeile mit den alten Werten abzurufen, geben eine
@@FETCH_STATUS
von -2 zurück. Die neuen Werte werden angezeigt, wenn die Aktualisierung über den Cursor erfolgt, indem die KlauselWHERE CURRENT OF
angegeben wird.
Hinweis
Wenn die Abfrage auf mindestens eine Tabelle ohne eindeutigen Index verweist, wird der Keyset-Cursor in einen statischen Cursor konvertiert.
DYNAMIC
Definiert einen Cursor, der alle an vorgenommenen Datenänderungen widerspiegelt Die Zeilen in der Ergebnismenge, wenn Sie um den Cursor scrollen und einen neuen Datensatz abrufen, unabhängig davon, ob die Änderungen innerhalb des Cursors oder von anderen Benutzern außerhalb des Cursors vorgenommen werden. Daher sind alle Anweisungen zum Einfügen, Aktualisieren und Löschen aller Benutzer über den Cursor sichtbar.Die Datenwerte, die Reihenfolge und die Zugehörigkeit zu den Zeilen können sich bei jedem Abruf ändern. Die Abrufoption ABSOLUTE
wird bei dynamischen Cursorn nicht unterstützt. Außerhalb des Cursors vorgenommene Aktualisierungen werden erst sichtbar, wenn sie festgeschrieben wurden (es sei denn, die Isolationsstufe der Cursortransaktion ist auf UNCOMMITTED
festgelegt). Angenommen, ein dynamischer Cursor ruft dann zwei Zeilen und dann eine andere Anwendung ab aktualisiert eine dieser Zeilen und löscht die andere. Wenn der dynamische Cursor diese Zeilen dann abruft, findet er die gelöschte Zeile nicht, zeigt jedoch die neuen Werte für die aktualisierte Zeile an.
FAST_FORWARD
Gibt eine FORWARD_ONLY
, READ_ONLY
Cursor mit aktivierten Leistungsoptimierungen. FAST_FORWARD
kann nicht angegeben werden, wenn auch SCROLL
oder FOR_UPDATE
angegeben ist. Dieser Cursortyp erlaubt keine Datenänderungen innerhalb des Cursors.
Hinweis
Sowohl FAST_FORWARD
als auch FORWARD_ONLY
kann in derselben DECLARE CURSOR
-Anweisung verwendet werden.
READ_ONLY
Verhindert Aktualisierungen, die über diesen Cursor vorgenommen werden. Der Cursor kann nicht in einer WHERE CURRENT OF
-Klausel in einer UPDATE
– oder DELETE
-Anweisung referenziert werden. Diese Option überschreibt die Standardfunktion eines zu aktualisierenden Cursors.
SCROLL_LOCKS
Gibt an, dass positionierte Aktualisierungen oder Löschungen, die über den Cursor vorgenommen werden, garantiert erfolgreich sind. SQL Server sperrt die Zeilen beim Einlesen in den Cursor, um ihre Verfügbarkeit für spätere Änderungen sicherzustellen. SCROLL_LOCKS
kann nicht angegeben werden, wenn FAST_FORWARD
oder STATIC
ebenfalls angegeben ist.
OPTIMISTISCH
Gibt an, dass über den Cursor vorgenommene positionierte Aktualisierungen oder Löschungen nicht erfolgreich sind, wenn die Zeile seit dem Einlesen in den Cursor aktualisiert wurde. SQL Server sperrt keine Zeilen, wenn sie in den Cursor eingelesen werden. Stattdessen werden Vergleiche von Zeitstempelspaltenwerten oder ein Prüfsummenwert verwendet, wenn die Tabelle keine Zeitstempelspalte enthält, um zu bestimmen, ob die Zeile nach dem Einlesen in den Cursor geändert wurde. Wenn die Zeile geändert wurde, schlägt die versuchte positionierte Aktualisierung oder Löschung fehl. OPTIMISTIC
kann nicht angegeben werden, wenn auch FAST_FORWARD
angegeben ist.
TYPE_WARNING
Gibt an, dass eine Warnmeldung gesendet wird an den Client, wenn der Cursor implizit vom angeforderten Typ in einen anderen konvertiert wird.
select_statement
Ist eine Standard-SELECT-Anweisung, die die Ergebnismenge des Cursors definiert. Die Schlüsselwörter COMPUTE
, COMPUTE BY
, FOR BROWSE
und INTO
sind in select_statement einer Cursordeklaration nicht zulässig.
Hinweis
Sie können einen Abfragehinweis in einer Cursordeklaration verwenden. Wenn Sie jedoch auch die Klausel FOR UPDATE OF
verwenden, geben Sie OPTION (<query_hint>)
nach FOR UPDATE OF
an.
SQL Server konvertiert den Cursor implizit in einen anderen Typ, wenn Klauseln in select_statement mit der Funktionalität des angeforderten Cursortyps in Konflikt stehen. Weitere Informationen finden Sie unter Implizite Cursorkonvertierungen.
Hinweise
DECLARE CURSOR
definiert die Attribute eines Transact-SQL-Servercursors, z Bildlaufverhalten und die Abfrage, mit der die Ergebnismenge erstellt wird, mit der der Cursor arbeitet. Die Anweisung OPEN
füllt die Ergebnismenge und FETCH
gibt eine Zeile aus der Ergebnismenge zurück. Die Anweisung CLOSE
gibt die aktuelle Ergebnismenge frei, die dem Cursor zugeordnet ist. Die Anweisung DEALLOCATE
gibt die vom Cursor verwendeten Ressourcen frei.
Die erste Form der Anweisung DECLARE CURSOR
verwendet die ISO Syntax zum Deklarieren des Cursorverhaltens. Die zweite Form von DECLARE CURSOR
verwendet Transact-SQL-Erweiterungen, mit denen Sie Cursor mit denselben Cursortypen definieren können, die in den Datenbank-API-Cursorfunktionen von ODBC oder ADO verwendet werden.
Sie können die beiden Formen nicht mischen. Wenn Sie die Schlüsselwörter SCROLL
oder INSENSITIVE
vor dem Schlüsselwort CURSOR
angeben, können Sie keine verwenden Schlüsselwörter zwischen den Schlüsselwörtern CURSOR
und FOR <select_statement>
. Wenn Sie Schlüsselwörter zwischen den Schlüsselwörtern CURSOR
und FOR <select_statement>
angeben, können Sie SCROLL
oder nicht angeben INSENSITIVE
vor dem Schlüsselwort CURSOR
.
Wenn ein DECLARE CURSOR
mit Transact-SQL-Syntax nicht READ_ONLY
angibt, OPTIMISTIC
oder SCROLL_LOCKS
lautet die Standardeinstellung wie folgt:
-
Wenn die
SELECT
unterstützt keine Aktualisierungen (unzureichende Berechtigungen, Zugriff auf Remotetabellen, die keine Aktualisierungen unterstützen usw.). Der Cursor lautetREAD_ONLY
. -
STATIC
undFAST_FORWARD
Cursor verwenden standardmäßigREAD_ONLY
. -
DYNAMIC
undKEYSET
Cursor verwenden standardmäßigOPTIMISTIC
Cursornamen können nur von anderen Transact-SQL-Anweisungen referenziert werden. Sie können nicht von Datenbank-API-Funktionen referenziert werden. Beispielsweise kann nach dem Deklarieren eines Cursors nicht auf den Cursornamen in OLE DB-, ODBC- oder ADO-Funktionen oder -Methoden verwiesen werden. Die Cursorzeilen können nicht mit den Abruffunktionen oder -methoden der APIs abgerufen werden. Die Zeilen können nur mit Transact-SQL-FETCH-Anweisungen abgerufen werden.
Nachdem ein Cursor deklariert wurde, können diese vom System gespeicherten Prozeduren verwendet werden, um die Eigenschaften des Cursors zu bestimmen.
Gespeicherte Systemprozeduren | Beschreibung |
---|---|
sp_cursor_list | Gibt eine Liste der derzeit in der Verbindung sichtbaren Cursor und ihrer Attribute zurück. |
sp_describe_cursor | Beschreibt die Attribute eines Cursors, z. B. ob es sich um einen Nur-Vorwärts- oder einen Bildlauf-Cursor handelt. |
sp_describe_cursor_columns | Beschreibt die Attribute der Spalten in der Cursor-Ergebnismenge. |
sp_describe_cursor_tables | Beschreibt die Basistabellen, auf die zugegriffen wird durch den Cursor. |
Variablen können als Teil der select_statement verwendet werden, die deklariert ein Cursor. Cursorvariablenwerte ändern sich nicht, nachdem ein Cursor deklariert wurde.
Berechtigungen
Berechtigungen von DECLARE CURSOR
gelten standardmäßig für Benutzer mit SELECT
Berechtigungen für die im Cursor verwendeten Ansichten, Tabellen und Spalten.
Einschränkungen und Einschränkungen
Sie können keine Cursor oder Trigger für eine Tabelle mit verwenden ein Clustered Columnstore-Index. Diese Einschränkung gilt nicht für nicht gruppierte Columnstore-Indizes. Sie können Cursor und Trigger für eine Tabelle mit einem nicht gruppierten Spaltenspeicherindex verwenden.
Beispiele
A. Verwenden des einfachen Cursors und der Syntax
Die beim Öffnen dieses Cursors generierte Ergebnismenge enthält alle Zeilen und alle Spalten in der Tabelle. Dieser Cursor kann aktualisiert werden, und alle Aktualisierungen und Löschungen werden in Abrufen dargestellt, die für diesen Cursor vorgenommen wurden. FETCH NEXT
ist der einzige verfügbare Abruf, da die Option SCROLL
nicht angegeben wurde.
B. Verwenden verschachtelter Cursor zum Erstellen von Berichtsausgaben
Das folgende Beispiel zeigt, wie Cursor verschachtelt werden können, um komplexe Berichte zu erstellen. Der innere Cursor wird für jeden Anbieter deklariert.