Ist es IMMER möglich, den Cursor zu vermeiden?

7

Ich suche nach einem Beispiel, bei dem die Verwendung eines Cursors unvermeidlich ist. Ich bin mir ziemlich sicher, dass es solche seltenen Fälle gibt, aber ich kann mir kein Szenario ausdenken. Jede Hilfe wäre wunderbar. Vielen Dank!

user18557
quelle
2
Sie können einen statischen Cursor immer mit einer while-Schleife und einer temporären Tabelle simulieren, aber zählt dies als Vermeidung eines Cursors? Fragen Sie nach Fällen, in denen ein Cursor die beste Lösung ist?
Martin Smith
1
Was ist dein Ziel?
Aaron Bertrand
2
Sag niemals nie. Es gibt wahrscheinlich immer einen legitimen Fall für die Verwendung einer bestimmten Funktion in SQL Server, egal wie selten. Es gibt wahrscheinlich sogar einen Grund für das automatische Schrumpfen.
Cade Roux
@CadeRoux Ich weiß nicht, ob ich so weit gehen würde ...
Aaron Bertrand

Antworten:

14

Sicher (und nehmen wir an, dass eine while-Schleife und ein Cursor für die Zwecke der Diskussion im Grunde dasselbe sind , und werfen alle Argumente aus, dass die Verwendung einer while-Schleife einen Cursor vermeidet, was einfach nur auf pedantischste Weise wahr ist):

  • Sie müssen eine gespeicherte Prozedur ausführen (z. B. eine vom Anbieter gespeicherte Prozedur, die Sie nicht berühren dürfen und die Sie verwenden müssen, um die Einhaltung / Unterstützung zu gewährleisten). Für jede Zeile in einem Satz.
  • Sie müssen jedem Benutzer eine eigene E-Mail senden (im Gegensatz zum Erstellen einer umfangreichen To / CC-Liste - nicht nur, weil dies nicht skalierbar ist, sondern auch, weil Sie die E-Mail möglicherweise für personalisieren müssen jeder Benutzer).

Es gibt auch einige Metadatenoperationen, bei denen Sie möglicherweise einen Cursor verwenden möchten, z. B. um alle Fremdschlüsseleinschränkungen für jede Tabelle zu deaktivieren und wieder zu aktivieren. Persönlich habe ich es immer vorgezogen, eine Zeichenfolge in einer Abfrage zu erstellen, die ich sofort ausführen kann, aber Sie möchten dies möglicherweise aus verschiedenen Gründen nicht tun. Als Beispiel habe ich in dieser Antwort keinen einzigen Cursor verwendet, obwohl ich es hätte tun können und es einfacher gewesen wäre zu schreiben . (Beachten Sie auch, dass Lösungen wie diese - und viele scheinbar satzbasierte Abfragen - technisch immer noch einen Cursor unter der Decke verwenden - Sie schreiben einfach nicht wirklich DECLARE CURSOR...)

Es kann auch recht komplex sein, eine satzbasierte Abfrage zu erstellen, die genau das tut, was ein Cursor tut, und oft ist die Zeitinvestition oder die Auswirkung auf die zukünftige Wartbarkeit aufgrund der Komplexität der Abfrage nicht wert, wenn der Cursor tatsächlich viel einfacher ist ( auch wenn es weniger effizient ist). Wenn Sie eine Cursorlösung mit einer satzbasierten Lösung vergleichen, stellen Sie aus Effizienzgründen sicher, dass Sie die effizientesten Cursoroptionen verwenden - diese können einen großen Unterschied machen .

Für normale Abfragen Sie bauen von Grund auf neu und ohne diese Einschränkungen, weiß ich nicht , dass es eine Situation, wo Sie haben einen Cursor zu verwenden, insbesondere als SQL Server Windowing - Funktionen und andere Funktionen hinzufügen weiter , die in mehr helfen Erweiterte satzbasierte Programmierung, für die normalerweise Cursor erforderlich waren.

Wenn Sie einen Cursor schreiben, sollten Sie sich fragen: "Gibt es eine satzbasierte Möglichkeit, dies zu tun?" Abhängig vom Zweck des Codes, wie oft er wiederverwendet wird, ob es sich um eine einmalige Aufgabe handelt usw. lautet die Antwort fast immer einseitig "Ja!" Eine durchaus zutreffende Antwort auf diese Frage könnte aber auch lauten: "Ja, aber wen interessiert das?"

Würde ein Beispiel ausreichen, bei dem ein Cursor tatsächlich die leistungsstärkste, unterstützte, dokumentierte und garantierte Lösung für ein Problem darstellt? Ein solches Beispiel ist die Berechnung der laufenden Summen in SQL Server <2012. Ich habe hier darüber gebloggt - und tatsächlich gezeigt, dass in meinem Anwendungsfall ein Cursor schneller war als alle anderen gängigen Ansätze, selbst die häufig empfohlenen (aber nicht garantierten, dokumentierten oder unterstützten) ) "schrullige Update" -Methode. (Nur wenn die neue 2012- LAGFunktion keine Option ist. In diesem Fall werden alle anderen Kreise umkreist.)

Aaron Bertrand
quelle