1. Aufgetretene Probleme
Tatsächlich handelt es sich nicht um ein großes Problem. O(∩_∩)O: Manchmal möchten wir die Ergebnisse möglicherweise direkt in der Stapelverarbeitung oder in gespeicherten Prozeduren auswählen. Zu diesem Zeitpunkt haben wir Wir benötigen ein Datenbankobjekt, das es uns ermöglicht, jede Datensatzzeile einzeln zu verarbeiten.
2. Das Konzept des Cursors
Um das obige Problem zu lösen, können wir ein Datenbankobjekt namens „Cursor“ verwenden.
Cursor (Cursor) kann als Datentyp betrachtet werden, der zum Durchlaufen der Ergebnismenge verwendet werden kann, was einem Zeiger oder einem Index in einem Array entspricht. Es verfügt über die folgenden Methoden zum Verarbeiten von Ergebnismengen:
Eine Zeile in der Ergebnismenge suchen
Nach einer Zeile oder einem Teil von Zeilen ab der Position der aktuellen Ergebnismenge suchen
Zielen Sie auf die Ergebnismenge ab. Ändern Sie die Daten der aktuellen Zeile
3. Verwendung des Cursors (Erstellen, Öffnen, Lesen, Schließen, Löschen)
[Cursor erstellen]
Und definieren Sie verschiedene Datentypmethoden, die ein wenig ähnlich sind, aber achten Sie darauf, nicht „@“ hinzuzufügen (tatsächlich gibt es auch „Cursortypvariablen“, die fast genau mit „Cursor“ identisch sind). Beim Definieren wird das @-Symbol verwendet. Das Folgende ist die Anweisung, die den Cursor definiert:
deklarieren Sie den Cursornamen Cursor [local|global] [forward_only|scroll]
für
wählen Sie die Abfrageanweisung
Cursor Es ist in zwei Typen unterteilt: lokaler Cursor und globaler Cursor. Lokal repräsentiert lokalen Cursor und global repräsentiert globalen Cursor (Standardwert, kann weggelassen werden). Wenn „forward_only“ (Standardwert, kann weggelassen werden) angegeben wird, ist der Cursor nur vorwärts, was bedeutet, dass Datensätze nur vom Anfang bis zum Ende extrahiert werden können. Wenn Sie zwischen Zeilen hin und her springen müssen, müssen Sie einen Bildlauf angeben. 【Cursor verwenden】 Es ist sinnlos, nur einen Cursor zu erstellen, ihn aber nicht zu verwenden. Nehmen wir das einfachste Beispiel, um die Schritte nach dem Erstellen eines Cursors zu demonstrieren: --[Cursor erstellen] C1-Cursor für die Auswahl von Xingming aus Yiren deklarierendeclare @xingming varchar (20) --[Cursor öffnen] öffne C1 --[Cursor lesen] nächstes von C1 in @xingming abrufen -- Das Merkmal von while ist, dass Sie es einmal schreiben müssen while(@@FETCH_STATUS=0) begin print 'Name:'+@ xingming
nächstes von C1 in @xingming abrufen Ende --[Cursor schließen] C1 schließen --[Cursor löschen】 C1 freigeben Ist die Methode zur Verwendung des Cursors whle(rs.next()){} in Java sehr ähnlich? Wenn rs.next() ausgeführt wird, wird einfach eine Zeile verschoben Wenn das Ende der Ergebnismenge nicht erreicht wird, wird der Schleifenkörper trotzdem ausgeführt. Das Gleiche gilt für die Verwendung eines Cursors. Wenn der Wert von @@FETCH_STATUS 0 ist, hat der Cursor das Ende noch nicht erreicht. Wenn es nicht mehr 0 ist, erreicht der Cursor das Ende und verlässt die Schleife. Nächstes vom Cursornamen in die Variablennamenliste abrufen ist eine Methode in fester Form zum Lesen des Cursorinhalts. Wenn die Abfrageanweisung mehrere Felder auswählt, müssen Sie diesen Satz auch verwenden, um beim Lesen mehreren Variablen Werte zuzuweisen. Schreiben Sie es also als Liste von Variablennamen. 【Globaler Cursor und Scroll-Cursor】 Der zuvor erwähnte globale Cursor und Scroll-Cursor, hier ist ein Beispiel: if(CURSOR_STATUS('global','CURSOR_2' ) !=-3) CURSOR_2 freigeben CURSOR_2 Cursor Scroll deklarieren --globaler Scroll Cursor für ausgewählte xingming,nicheng,xingbie aus yiren --der erste T- SQL-Batch-Start CURSOR_2 öffnen @seq int deklarieren, @xingming varchar(20),@nicheng varchar(50),@xingbie nchar
Setze @seq=4 fetch absolute @seq from CURSOR_2 into @xingming,@nicheng,@xingbie if (@@FETCH_STATUS=0) begin print '+cast(@seq as varchar)+' Künstler ist: '+@xingmingprint case @xingbie, wenn 'männlich', dann 'er', wenn 'weiblich', dann 'sie' endet +' Spitzname ist: '+@nicheng end close CURSOR_2 go - -Das zweite T-SQL Batch startet CURSOR_2 öffnen @seq int deklarieren, @xingming varchar(20),@nicheng varchar(50),@xingbie nchar setze @seq=5 – aufgeteilt in zwei Stapel, muss @seq erneut definieren, absolute @seq von CURSOR_2 in @xingming,@nicheng,@xingbie abrufen if(@@FETCH_STATUS =0) begin print 'Der '+cast(@seq as varchar)+' Künstler ist: '+@xingmingprint case @xingbie when 'male ' dann 'er', wenn 'weiblich', dann 'ihr' Ende Der Spitzname von + ist: '+@nicheng Ende CURSOR_2 schließen go --Cursor im dritten Batch löschen CURSOR_2 freigeben Wenn die Scroll-Option aktiviert ist, kann Fetch verwendet werden, um als nächstes zu lesen (zurückzugehen), prior (vorwärts gehen), first (erste Zeile), last (letzte Zeile), absolut (numerischen Wert verwenden, um die absolute Linie zu lokalisieren), relativ (numerischen Wert verwenden, um die relative Linie zu positionieren).
Sobald ein globaler Cursor definiert ist, ist er immer vorhanden, sodass jeder Stapel ihn sehen kann. Es verschwindet erst, wenn Sie es mithilfe von „Deallocate“ entfernen. CURSOR_STATUS('global','CURSOR_2') kann seinen Status überprüfen.
【Cursor Nesting】
Da es die Systemleistung stark beeinflusst, werfen Sie einfach einen kurzen Blick darauf.
if(CURSOR_STATUS('global','CURSOR_3')!=-3) CURSOR_3 freigeben
CURSOR_3-Cursor deklarieren für
Yanchuid aus Yanchu auswählen
öffne CURSOR_3
deklariere @ycid int
hol als nächstes von CURSOR_3
in @ycid
while(@@FETCH_STATUS=0)
beginnen
print 'Der Künstler, der an der Aufführung '+cast(@ycid as varchar)+' teilnimmt, ist:'
deklarieren Sie den CURSOR_4-Cursor für
wählen Sie Xingming aus yiren where yirenid in
(select yirenid from yanchuyiren where yanchuid=@ycid)
--Dieser Satz verwendet eine Unterabfrage, und tatsächlich können Sie einen anderen Cursor verschachteln
deklarieren @ xingming varchar(50)
CURSOR_4 öffnen
Nächstes von CURSOR_4 in @xingming abrufen
while(@@FETCH_STATUS=0)
begin
@xingming drucken
Nächstes von CURSOR_4 in @xingming abrufen
Ende
CURSOR_4 schließen
CURSOR_4 freigeben
Nächstes abrufen von CURSOR_3
in @ycid
print ''
end
close CURSOR_3
CURSOR_3 freigeben
[ Cursorvariable]
Cursorvariable ist eine Möglichkeit, einen Cursor wirklich als Datentyp zu verwenden. Der Unterschied zwischen einer Cursorvariablen und einem Cursorobjekt besteht darin, ob es ein @ gibt. Wenn Sie eine Cursorvariable erstellen, deklarieren Sie zuerst den @cursor-Variablennamen „Cursor“ und legen Sie dann den @cursor-Variablennamen = Cursor für die SELECT-Anweisung fest.
deklariere @c1 CURSOR
setze @c1=Cursor für die Auswahl von Xingming aus Yiren
öffne @c1
deklariere @xingming varchar(50)
nächstes von @c1 in @xingming abrufen
@xingming drucken
@c1 schließen
@c1 freigeben
4. Hinweis zu Cursorn Matters
【Nachteile von Cursorn】
Durch die Verwendung eines Cursors wird die Ergebnismenge einzeln herausgenommen und verarbeitet, was die Belastung des Servers erhöht ist weitaus geringer als die Verwendung der Standardergebnismenge. Hohe Effizienz. Wenn Sie den Cursor nicht verwenden können, versuchen Sie daher, ihn nicht zu verwenden.
[Zusätzliche Erklärung der Cursor]
Wenn wir einfach einen Cursor öffnen, zeigt er nicht auf den ersten Datensatz, sondern auf den Anfang des ersten Datensatzes. Wir können ein Buch als Analogie verwenden. Der Cursor kann nicht nur auf die Datensätze im Datensatz (jede Seite des Buchinhalts) zeigen, sondern auch auf Stellen, an denen es außerhalb des Datensatzes keine Datensätze gibt (das Cover und die Rückseite). Cover des Buches).
@@fetch_status hat drei Werte: 0 gibt an, dass der Abruf normal ausgeführt wird, -1 gibt an, dass der Abruf die Ergebnismenge überschreitet, und -2 gibt an, dass die Zeile, auf die der Abruf zeigt, nicht mehr existiert.
5. Ändern Sie die gespeicherte Paging-Abfrageprozedur, verwenden Sie den Cursor
Ändern Sie den ersten Zweig in den folgenden Code:
if @currentpage >1
begin
if @currentpage>@totalpages
begin
set @currentpage = @totalpages
end
deklariere @start int , @count int
set @count = 0
set @start = @currentpage*@pagesize+1
set @sql='declarecursor_1 Cursor scrollen für Auswahl * from '
+@tablename+' order by '+@idname
exec(@sql)
open Cursor_1
fetch relative @start,@pagesize von Cursor_1
while @@fetch_status=0
begin
set @count = @count+1
nächstes von Cursor_1 abrufen
wenn @count=@pagesize-1
Pause
Ende
Cursor_1 schließen
Cursor_1 freigeben
Ende
Und entfernen Sie das
exec(@sql)
vor dem ursprünglichen Go. Wenn Sie diesen Satz nicht entfernen, wird dieser Satz am Ende der gespeicherten Prozedur erneut ausgeführt und somit versehentlich erneut der Cursor @cursor_1 generiert.