Die Abfrageanweisung kann mehrere Datensätze zurückgeben. Wenn die Datenmenge sehr groß ist, muss ein Cursor verwendet werden, um die Datensätze im Abfrageergebnissatz einzeln zu lesen. Anwendungen können die Daten nach Bedarf scrollen oder durchsuchen. In diesem Artikel werden das Konzept, die Klassifizierung und die Grundfunktionen von Cursorn vorgestellt.
1: Cursor verstehen
Ein Cursor ist ein Datenzugriffsmechanismus in SQL Server, der Benutzern den Zugriff auf einzelne Datenzeilen ermöglicht. Benutzer können jede Zeile einzeln verarbeiten und so den Systemaufwand und mögliche Blockierungssituationen reduzieren. Benutzer können auch den durch diese Daten generierten SQL-Code verwenden und ihn sofort ausführen oder ausgeben.
1. Das Konzept des Cursors
Ein Cursor ist eine Methode zur Datenverarbeitung, die hauptsächlich in gespeicherten Prozeduren, Triggern und T_SQL-Skripten verwendet wird. Sie stellen den Inhalt der Ergebnismenge anderen T_SQL zur Verfügung Aussagen. Die Möglichkeit, sich vorwärts oder rückwärts durch Daten zu bewegen, während ein Ergebnissatz angezeigt oder verarbeitet wird. Ähnlich wie ein Zeiger in der C-Sprache kann er auf eine beliebige Position in der Ergebnismenge zeigen. Wenn die Ergebnismenge einzeln verarbeitet werden soll, muss eine Cursorvariable deklariert werden, die auf die Ergebnismenge zeigt.
Die Datenoperationsergebnisse in SQL Server sind alle satzorientiert und es gibt keine Ausdrucksform zur Beschreibung eines einzelnen Datensatzes in der Tabelle, es sei denn, die WHERE-Klausel wird verwendet, um die Abfrageergebnisse einzuschränken kann diese Funktion bereitstellen, und der Verwendungs- und Bedienungsprozess von Cursorn ist flexibler und effizienter.
2. Vorteile von Cursorn
Die SELECT-Anweisung gibt eine Ergebnismenge zurück, aber manchmal können Anwendungen nicht immer die gesamte Ergebnismenge effektiv verarbeiten, und Cursor stellen dies bereit. Ein Mechanismus, der jeweils einen Datensatz extrahiert aus einer Ergebnismenge, die mehrere Datensätze enthält. Der Cursor ist immer mit einer One-Hop-SQL-Select-Anweisung verknüpft und besteht aus der Ergebnismenge und der Cursorposition, die auf einen bestimmten Datensatz zeigt. Die Verwendung von Cursorn bietet die folgenden Vorteile:
(1) Ermöglicht dem Programm, jedes Mal dieselben oder unterschiedliche Operationen in der von der SELECT-Abfrageanweisung zurückgegebenen Reihe von Zeilen auszuführen, anstatt dieselbe Operation für die gesamte Menge auszuführen Satz.
(2) Bietet die Möglichkeit, Zeilen basierend auf der Cursorposition zu löschen und zu aktualisieren.
(3) Cursor dienen als Brücke zwischen Datenbankverwaltungssystemen und Anwendungsdesign und verbinden die beiden Verarbeitungsmethoden.
3. Klassifizierung von Cursorn
SQL Server unterstützt drei Cursor-Implementierungen:
(1). Der Transact_SQL-Cursor
basiert hauptsächlich auf der DECLARE CURSOR-Syntax Wird für T_SQL-Skripte, gespeicherte Prozeduren und Trigger verwendet. T_SQL-Cursor werden auf dem Server implementiert und durch T_SQL-Anweisungen verwaltet, die vom Client an den Server gesendet werden. Sie können auch in Batches, gespeicherten Prozeduren oder Triggern enthalten sein.
(2). API-Servercursor
Unterstützt API-Cursorfunktionen in OLE DB und ODBC, und API-Servercursor werden auf dem Server implementiert. Jedes Mal, wenn eine Clientanwendung eine API-Cursorfunktion aufruft, übermittelt der SQL Server Native Client OLE DB-Anbieter oder ODBC-Treiber die Anforderung an den Server, den API-Servercursor zu bearbeiten.
(3). Clientseitige Cursor
werden intern vom SQL Server Native Client ODBC-Treiber und der DLL implementiert, die die ADO-API implementiert. Clientseitige Cursor werden implementiert, indem alle Ergebnissatzzeilen auf der Clientseite zwischengespeichert werden. Jedes Mal, wenn eine Clientanwendung eine API-Cursorfunktion aufruft, führt der SQL Server Native Client ODBC-Treiber oder die ADO-DLL eine Cursoroperation für die Zeilen im zwischengespeicherten Ergebnissatz auf dem Client aus.
Da T_SQL-Cursor und Server-Cursor auf dem Server implementiert sind, werden sie gemeinsam als Server-Cursor bezeichnet.
ODBC und ADO definieren 4 Cursortypen, die von Microsoft SQL Server unterstützt werden, sodass 4 Cursortypen für T_SQL-Cursor angegeben werden können.
Die vier Arten von API-Server-Cursoren, die von SQL Server unterstützt werden, sind:
(i) Nur-Eingabe-Cursor
Nur-Eingabe-Cursor unterstützt kein Scrollen, sondern nur Unterstützt den Cursor von Anfang an. In der Reihenfolge von Ende zu Ende extrahieren. Zeilen können erst abgerufen werden, nachdem sie aus der Datenbank extrahiert wurden. Bei allen vom aktuellen Benutzer ausgegebenen oder von anderen Benutzern übermittelten INSERT-, UPDATE- und DELETE-Anweisungen, die sich auf Zeilen im Ergebnissatz auswirken, sind die Auswirkungen sichtbar, wenn diese Zeilen aus dem Cursor extrahiert werden.
Da der Cursor nicht rückwärts scrollen kann, sind die meisten Änderungen, die an einer Zeile in der Datenbank vorgenommen werden, nachdem die Zeile abgerufen wurde, nicht durch den Cursor sichtbar. Wenn ein Wert verwendet wird, um die Position einer Zeile in einem geänderten Ergebnissatz zu bestimmen (z. B. beim Aktualisieren einer Spalte, die von einem Clustered-Index abgedeckt wird), ist der geänderte Wert durch den Cursor sichtbar.
(ii). Statische Cursor
Statische Cursor von SQL Server sind immer schreibgeschützt. Die vollständige Ergebnismenge wird beim Öffnen des Cursors in tempdb erstellt. Ein statischer Cursor zeigt die Ergebnismenge immer so an, wie sie ist, wenn der Cursor geöffnet wird.
Der Cursor spiegelt keine in der Datenbank vorgenommenen Änderungen wider, die sich auf die Mitgliedschaft in der Ergebnismenge auswirken, und auch Änderungen an den Spaltenwerten der in der Ergebnismenge zusammengefassten Zeilen werden danach nicht angezeigt Öffnen des Cursors Neu eingefügte Zeilen in der Datenbank, auch wenn diese Zeilen die Suchbedingungen der Cursor-SELECT-Anweisung erfüllen. Wenn die Zeilen, aus denen sich die Ergebnismenge zusammensetzt, von anderen Benutzern aktualisiert werden, werden die neuen Datenwerte nicht im statischen Cursor angezeigt. Ein statischer Cursor zeigt Zeilen an, die aus den Daten gelöscht wurden, nachdem der Cursor geöffnet wurde. UPDATE-, INSERT- oder DELETE-Vorgänge werden nicht in einem statischen Cursor widergespiegelt (es sei denn, der Cursor wird geschlossen und erneut geöffnet) oder sogar Änderungen, die über dieselbe Verbindung vorgenommen werden, die den Cursor geöffnet hat.
(iii) Tastengesteuerter Cursor
Die Zugehörigkeit und Reihenfolge der Zeilen in diesem Cursor sind festgelegt. Ein Keyset-gesteuerter Cursor wird durch eine Reihe eindeutiger Bezeichner (Schlüssel) gesteuert, die als Keyset bezeichnet werden. Aus einem Satz von Spalten wird ein Schlüssel generiert, der jede Zeile des Ergebnissatzes eindeutig identifiziert. Ein Schlüsselsatz ist ein Satz von Schlüsselwerten aus allen Zeilen, die beim Öffnen des Cursors die Anforderungen der SELECT-Anweisung erfüllen. Der Keyset, der einem Keyset-gesteuerten Cursor entspricht, wird in tempdb generiert, wenn der Cursor geöffnet wird.
(IV). Dynamischer Cursor
Der dynamische Cursor ist das Gegenteil des statischen Cursors. Dynamische Cursor spiegeln alle Änderungen wider, die beim Scrollen des Cursors an der Ergebnismenge vorgenommen werden. Die Zeilendatenwerte, die Reihenfolge und die Mitglieder im Ergebnissatz ändern sich bei jedem Abruf. Alle UPDATE-, INSERT- und DELETE-Anweisungen aller Benutzer sind durch den Cursor sichtbar. Sie sind sofort sichtbar, wenn sie über einen Cursor mit API-Funktionen wie SQLSePos oder der T_SQL WHERE CURRENT OF-Klausel aktualisiert werden. Außerhalb des Cursors vorgenommene Aktualisierungen sind erst sichtbar, wenn sie festgeschrieben werden, es sei denn, die Transaktionsisolationsstufe des Cursors ist auf „Lesen ohne Festschreibung“ eingestellt.
2: Grundlegende Operationen des Cursors
1. Deklarieren Sie den Cursor
Ein Cursor besteht hauptsächlich aus zwei Teilen: der Cursor-Ergebnismenge und der Cursor-Ergebnismenge der von der SELECT-Anweisung zurückgegebenen Zeilen, die den Cursor definieren, ist die Cursorposition ein Zeiger auf eine bestimmte Zeile in dieser Ergebnismenge.
Bevor Sie einen Cursor verwenden, müssen Sie den Cursor deklarieren. Die Deklaration eines Cursors umfasst die Definition des Scrollverhaltens des Cursors und der vom Benutzer generierten Abfrage Der Cursor. Das Syntaxformat ist wie folgt:
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FOR select_statement [ FOR UPDATE [ OF column_name [,...n] ] ]
cursor_name: ist der Name des definierten T_SQL-Servercursors.
LOKAL: Der Gültigkeitsbereich dieses Cursors ist lokal für den Stapel, die gespeicherte Prozedur oder den Trigger, in dem er erstellt wird.
GLOBAL: Gibt an, dass der Gültigkeitsbereich des Cursors global ist.
FORWARD_ONLY: Gibt an, dass der Cursor nur von der ersten Zeile zur letzten Zeile scrollen kann. FETCH NEXT ist die einzige unterstützte Abrufoption. Wenn die Schlüsselwörter STATIC, KEYSET und DYNAMIC nicht angegeben sind, wenn FORWARD_ONLY angegeben ist, fungiert der Cursor als DYNAMIC-Cursor. Wenn sowohl FORWARD_ONLY als auch SCROLL angegeben sind, fungiert der Cursor als DYNAMIC-Cursor Die Schlüsselwörter STATIC, KEYSET und DYNAMIC sind angegeben, andernfalls ist der Standardwert FORWARD_ONLY. STATISCHE, KEYSET- und DYNAMISCHE Cursor sind standardmäßig auf SCROLL eingestellt. Im Gegensatz zu Datenbank-APIs wie ODBC und ADO unterstützen STATIC-, KEYSET- und DYNAMIC-T_SQL-Cursor FORWARD_ONLY.
STATISCH: Definieren Sie einen Cursor, um eine temporäre Kopie der Daten zu erstellen, die vom Cursor verwendet werden. Alle Anfragen für den Cursor werden daher nicht aus der temporären Tabelle in tempdb beantwortet. Änderungen an der Basistabelle werden nicht in den während des Abrufvorgangs zurückgegebenen Daten widergespiegelt, und der Cursor lässt keine Änderungen zu.
KEYSET: Gibt an, dass beim Öffnen des Cursors die Zugehörigkeit und Reihenfolge der Zeilen unter dem Cursor festgelegt werden. Die Schlüssel, die Zeilen eindeutig identifizieren, sind in einer Tabelle in tempdb namens „keyset“ integriert.
DYNAMISCH: Definiert einen Cursor, der alle Datenänderungen widerspiegelt, die an Zeilen innerhalb der Ergebnismenge vorgenommen werden, während der Cursor gescrollt wird. Die Datenwerte, die Reihenfolge und die Zugehörigkeit der Zeilen ändern sich bei jedem Abruf, und die Abrufoption ABSOLUTE wird bei dynamischen Cursorn nicht unterstützt.
FAST_FORWARD: Gibt die FORWARD_ONLY- und READ_ONLY-Cursor mit aktivierter Leistungsoptimierung an. Wenn SCROLL oder FOR_UPDATE angegeben ist, kann FAST_FORWARD nicht angegeben werden.
SCROLL_LOCKS: Gibt an, dass Positionierungsaktualisierungen oder -löschungen durch Cursor erfolgreich sein müssen. SQL Server sperrt Zeilen, wenn sie in einen Cursor eingelesen werden, um sicherzustellen, dass sie später geändert werden können. SCROLL_LOCKS kann nicht angegeben werden, wenn auch FAST_FORWARD oder STATIC angegeben ist.
OPTIMISTISCH: Gibt an, dass positionierte Aktualisierungen oder positionierte Löschungen über den Cursor nicht erfolgreich sind, wenn die Zeile seit dem Einlesen des Cursors aktualisiert wurde. Wenn eine Zeile in einen Cursor eingelesen wird, sperrt SQL Server die Zeile nicht. Stattdessen ermittelt er mithilfe des Zeitstempelspaltenwerts, ob die Zeile seit dem Einlesen in den Cursor geändert wurde Stattdessen wird der Prüfsummenwert verwendet, um festzustellen, ob bei einer Änderung der Zeile ein Versuch einer positionierten Aktualisierung oder Löschung fehlschlägt und OPTIMISTIC nicht angegeben werden kann, wenn auch FAST_FORWARD angegeben ist.
TYPE_WARNING: Gibt an, dass eine Warnmeldung an den Client gesendet wird, wenn der Cursor implizit vom angeforderten Typ in einen anderen Typ konvertiert wird.
select_statement: ist die Standard-SELECT-Anweisung, die die Cursor-Ergebnismenge definiert.
[Beispiel] Deklarieren Sie einen Cursor mit dem Namen „cursor_fruit“
USE sample_db; GO DECLARE cursor_fruit CURSOR FOR SELECT f_name,f_price FROM fruits;
2. Öffnen Sie den Cursor
Muss vor der Verwendung des Cursors geöffnet werden Cursor, die Syntax zum Öffnen eines Cursors lautet wie folgt:
OPEN [ GLOBAL ] cursor_name | cursor_variable_name;
GLOBAL: Geben Sie Cursorname als globalen Cursor an.
cursor_name: Der Name des deklarierten Cursors. Wenn sowohl der globale als auch der lokale Cursor Cursorname als Namen verwenden, bezieht sich Cursorname auf den globalen Cursor, wenn GLOBAL angegeben ist, andernfalls bezieht sich Cursorname auf den lokalen Cursor.
cursor_variable_name: Der Name der Cursorvariablen.
[Beispiel] Öffnen Sie den im obigen Beispiel deklarierten Cursor namens „cursor_fruit“
USE sample_db; GO OPEN cursor_fruit;
3. Lesen Sie die Daten im Cursor
Nach dem Öffnen des Cursors können Sie lesen der Cursor Der FETCH-Befehl kann eine bestimmte Datenzeile im Cursor lesen. Die Syntax von FETCH lautet wie folgt:
ETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM ] { { [GLOBAL ] cursor_name } | @cursor_variable_name} [ INTO @variable_name [ ,...n ] ]
NEXT:紧跟当前行返回结果行,并且当前行递增为返回行,如果FETCH NEXT为对游标的第一次提取操作,则返回结果集中的第一行。NEXT为默认的游标提取选项。
PRIOR:返回紧邻当前行前面的结果行,并且当前行递减为返回行,如果FETCH PRIOR为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。
FIRST:返回游标中的第一行并将其作为当前行。
LAST:返回游标中的最后一行并将其作为当前行。
ABSOLUTE { n | @nvar }:如果n或@nvar为正,则返回从游标头开始向后n行的第n行,并将返回行变成新的当前行。如果n或@nvar为负,则返回从游标末尾开始向前的n行的第n行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为int、tinyint或smallint.
RELATIVE { n | @nvar }:如果n或@nvar为正,则返回从当前行开始向后的第n行。如果n或@nvar为负,则返回从当前行开始向前的第n行。如果n或@nvar为0,则返回当前行,对游标第一次提取时,如果在将n或@nvar设置为负数或0的情况下指定FETCH RELATIVE,则不返回行,n必须是整数常量,@nvar的数据类型必须是int、tinyint或smallint.
GLOBAL:指定cursor_name是全局游标。
cursor_name:已声明的游标的名称。如果全局游标和局部游标都使用cursor_name作为其名称,那么如果指定了GLOBAL,则cursor_name指的是全局游标,否则cursor_name指的是局部游标。
@cursor_variable_name:游标变量名,引用要从中进行提取操作的打开的游标。
INTO @variable_name [ ,…n ]:允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果集列的数据类型相匹配,或是结果集列数据类型所支持的隐士转换。变量的数目必须与游标选择列表中的列数一致。
【例】使用名称为cursor_fruit的光标,检索fruits表中的记录,输入如下:
USE sample_db; GO FETCH NEXT FROM cursor_fruit WHILE @@FETCH_STATUS=0 BEGIN FETCH NEXT FROM cursor_fruit END;
4.关闭游标
SQL Server 在打开游标之后,服务器会专门为游标开辟一定的内存空间存放游标操作的数据结果集,同时游标的使用也会根据具体情况对某些数据进行封锁。所以在不使用游标的时候,可以将其关闭,以释放游标所占用的服务器资源,关闭游标使用CLOSE语句。语法格式如下:
CLOSE [ GLOBAL ] cursor_name | cursor_variable_name
【例】关闭名称为cursor_fruit的游标
CLOSE cursor_fruit;
5.释放游标
游标操作的结果集空间虽然被释放了,但是游标本身也会占用一定的计算集资源,所以使用完游标之后,为了收回被游标占用的资源,应该将游标释放。释放游标使用DEALLOCATE语句,语法格式如下:
DEALLOCATE [GLOBAL] cursor_name | @ccursor_variable_name
@ccursor_variable_name:游标变量的名称,@ccursor_variable_name必须为cursor类型。
DEALLOCATE @ccursor_variable_name 语句只删除对游标变量名称的引用,直到批处理、存储过程或触发器结束时变量离开作用域,才释放变量。
【例】使用DEALLOCATE语句释放名称为cursor_fruit的变量,输入如下:
DEALLOCATE cursor_fruit;
三:游标的运用
1.使用游标变量
声明变量用DECLARE,为变量赋值可以用set或SELECT语句,对于游标变量的声明和赋值,其操作基本相同。在具体使用时,首先要创建一个游标,将其打开后,将游标的值赋给游标变量,并通过FETCH语句从游标变量中读取值,最后关闭释放游标。
【例】声明名称为@varCursor的游标变量,输入如下:
DECLARE @varCursor Cursor --声明游标变量 DECLARE cursor_fruit CURSOR FOR --创建游标 SELECT f_name,f_price FROM fruits; OPEN cursor_fruit --打开游标 SET @varCursor=cursor_fruit --为游标变量赋值 FETCH NEXT FROM @varCursor --从游标变量中读取值 WHILE @@FETCH_STATUS=0 --判断FETCH语句是否执行成功 BEGIN FETCH NEXT FROM @varCursor --读取游标变量中的数据 END CLOSE @varCursor --关闭游标 DEALLOCATE @varCursor; --释放游标
2.用游标为变量赋值
在游标的操作过程中,可以使用FETCH语句将数据值存入变量,这些保持表中列值的变量可以在后面的程序中使用。
【例】创建游标cursor_variable,将fruits表中的记录f_name,f_price值赋给变量@fruitName和@fruitPrice,并打印输出。
3.用ORDER BY 子句改变游标中的执行顺序
游标是一个查询结果集,那么能不能对结果进行排序呢?答案是否定的。与基本的SELECT语句中的排序方法相同,ORDER BY子句添加到查询中可以对游标查询的结果排序。
注意:只有出现在游标中的SELECT语句中的列才能作为ORDER BY 子句的排序列,而对与非游标的SELECT语句中,表中任何列都可以作为ORDER BY 的排序列,即使该列没有出现在SELECT语句的查询结果列中。
【例】声明名称为cursor_order的游标,对fruits表中的记录按照价格字段降序排列,输入语句如下:
4.用游标修改数据
【例】声明整型变量@sid=101,然后声明一个对fruits表进行操作的游标,打开该游标,使用FETCH NEXT方法来获取游标中的每一行的数据,如果获取到的记录的s_id的字段值与@sid值相同,将s_id=@sid的记录中的f_price修改为12.2,最后关闭释放游标,输入如下:
5.用游标删除数据
使用游标删除数据时,既可以删除游标结果集中的数据,也可以删除基本表中的数据
【例】使用游标删除fruits表中s_id=102的记录,如下
以上例子的sql脚本:
USE sample_db; create TABLE fruits( f_id int IDENTITY(1,1) PRIMARY KEY,--水果id s_id int not null, --供应商id f_name varchar(255) not null,--水果名称 f_price decimal(8,2) not null --水果价格 ); insert into fruits (s_id,f_name,f_price) values (101,'apple',5.8), (102,'blackberry',6.8), (105,'orange',4.5), (102,'banana',3.5), (103,'lemon',8.0), (104,'grape',7.6), (101,'melon',10.5); --1.声明名称为cursor_fruit的游标 USE sample_db; GO DECLARE cursor_fruit CURSOR FOR SELECT f_name,f_price FROM fruits; --2.打开游标 OPEN cursor_fruit; --3.读取游标中的数据 --【例】使用名称为cursor_fruit的光标,检索fruits表中的记录,输入如下: USE sample_db; GO FETCH NEXT FROM cursor_fruit WHILE @@FETCH_STATUS=0 BEGIN FETCH NEXT FROM cursor_fruit END; --4.关闭关闭名称为cursor_fruit的游标 CLOSE cursor_fruit --5.释放游标 DEALLOCATE cursor_fruit; --游标的运用 --1.使用游标变量 --声明名称为@varCursor的游标变量 DECLARE @varCursor Cursor --声明游标变量 DECLARE cursor_fruit CURSOR FOR --创建游标 SELECT f_name,f_price FROM fruits; OPEN cursor_fruit --打开游标 SET @varCursor=cursor_fruit --为游标变量赋值 FETCH NEXT FROM @varCursor --从游标变量中读取值 WHILE @@FETCH_STATUS=0 --判断FETCH语句是否执行成功 BEGIN FETCH NEXT FROM @varCursor --读取游标变量中的数据 END CLOSE @varCursor --关闭游标 DEALLOCATE @varCursor; --释放游标 --2.用游标为变量赋值 --创建游标cursor_variable,将fruits表中的记录f_name,f_price值赋给变量@fruitName和@fruitPrice,并打印输出。 DECLARE @fruitName varchar(50),@fruitPrice DECIMAL(8,2) DECLARE cursor_variable CURSOR FOR SELECT f_name,f_price FROM fruits WHERE s_id=101; OPEN cursor_variable FETCH NEXT FROM cursor_variable INTO @fruitName,@fruitPrice PRINT '编号为101的供应商提供的水果种类和价格为:' WHILE @@FETCH_STATUS=0 BEGIN PRINT @fruitName+' '+STR(@fruitPrice,8,2) FETCH NEXT FROM cursor_variable INTO @fruitName,@fruitPrice END CLOSE cursor_variable DEALLOCATE cursor_variable; --3.用ORDER BY子句改变游标中的执行顺序 --声明名称为cursor_order的游标,对fruits表中的记录按照价格字段降序排列,输入语句如下: DECLARE cursor_order CURSOR FOR SELECT f_id,f_name,f_price FROM fruits ORDER BY f_price DESC OPEN cursor_order FETCH NEXT FROM cursor_order WHILE @@FETCH_STATUS=0 FETCH NEXT FROM cursor_order CLOSE cursor_order DEALLOCATE cursor_order; --4.用游标修改数据 --【例】声明整型变量@sid=101,然后声明一个对fruits表进行操作的游标,打开该游标, --使用FETCH NEXT方法来获取游标中的每一行的数据, --如果获取到的记录的s_id的字段值与@sid值相同,将s_id=@sid的记录中的f_price修改为12.2,最后关闭释放游标,输入如下: DECLARE @sid INT,@id INT =101 DECLARE cursor_fruit CURSOR FOR SELECT s_id FROM fruits; OPEN cursor_fruit FETCH NEXT FROM cursor_fruit INTO @sid WHILE @@FETCH_STATUS=0 BEGIN IF @sid=@id BEGIN UPDATE fruits SET f_price=11.1 WHERE s_id=@id END FETCH NEXT FROM cursor_fruit INTO @sid END CLOSE cursor_fruit DEALLOCATE cursor_fruit; SELECT * FROM fruits where s_id=101; --5.使用游标删除数据 --【例】使用游标删除fruits表中s_id=102的记录,如下 DECLARE @sid1 INT,@id1 int=102 DECLARE cursor_delete CURSOR FOR SELECT s_id FROM fruits; OPEN cursor_delete FETCH NEXT FROM cursor_delete INTO @sid1 WHILE @@FETCH_STATUS=0 BEGIN IF @sid1=@id1 BEGIN DELETE FROM fruits where s_id=@id1 END FETCH NEXT FROM cursor_delete INTO @sid1 END CLOSE cursor_delete DEALLOCATE cursor_delete; SELECT * FROM fruits where s_id=102;