2009-07-05 8 views
2

Ich möchte eine Tabelle/Ansicht durchlaufen und dann einen Prozess starten (z. B. einen Job ausführen, eine E-Mail senden) basierend auf einigen Kriterien.SQL Server - Standardmuster für zeilenweise Operationen in einer Tabelle/Ansicht

Meine willkürliche Einschränkung hier ist, dass ich diese in der Datenbank tun möchten sich, T-SQL auf einem gespeicherten proc, Trigger usw.

Ist dieses Szenario erfordert Cursor, oder gibt es eine andere einheimische T -SQL-Reihe-basierte Operation, die ich nutzen kann?

Antwort

1

Ihre beste Wette ist ein Cursor. Da SQL deklarativ und satzbasiert ist, ist jede "Problemumgehung", die versucht, SQL zu zwingen, imperative reihenorientierte Operationen auszuführen, unzuverlässig und kann brechen. Z.B. Der Optimierer kann Ihre "Operation" aus der Ausführung herausschneiden oder in seltsamer Reihenfolge oder für eine unerwartete Anzahl von Malen ausführen.

Der allgemeine falsche Name Cursor ist, wenn sie anstelle von Set-based-Operationen (wie eine Berechnung und Aktualisierung oder einen Bericht zurückgeben) bereitgestellt werden, da der Entwickler eine Set-orientierte Art der gleichen Funktionalität nicht gefunden hat. Aber für Nicht-SQL-Operationen (dh einen Prozess starten) sind sie geeignet.

Sie können auch einige Variationen des Cursorthemas verwenden, z. B. clientseitige Iteration durch eine Ergebnismenge. Das ist dem Cursor sehr ähnlich, obwohl keine expliziten Cursor verwendet werden.

1

Der Standard Weg dies zu tun wäre SSIS. Verwenden Sie einfach einen Task "SQL ausführen", um die Zeilen abzurufen, und einen Task-Container "Für jeden", um einmal pro Zeile zu iterieren. Führen Sie im Container die gewünschten Aufgaben aus und sie haben Zugriff auf die Spalten jeder Zeile.

+0

@John ssis verwenden, wie würde ich, dass jede Reihe gewährleisten nur einmal betätigt wird auf (vorausgesetzt, ich die Fähigkeit, irgendwann wollte Führen Sie mehrere gleichzeitige ssis-Aufgaben mit der jobs-Tabelle aus, um einen höheren Durchsatz zu erreichen. Ich nehme an, ich brauche eine temporäre "in Arbeit" -Flagge, um Konflikte zu vermeiden. Kann das etwas für mich bedeuten oder müsste ich diese Logik noch selbst implementieren? – Howiecamp

+0

@Howiecamp: Ich weiß nicht, was du meinst. Der SQL ausführen-Task würde eine Ergebnismenge erzeugen, die Zeilen enthält. Die For-For-Task würde einmal pro Zeile ausgeführt. Was müssen Sie noch tun, um sicherzustellen, dass jede Zeile nur einmal bearbeitet wird? –

0

Wenn Sie planen, eine E-Mail an jeden Datensatz mit einer E-Mail-Adresse (oder einer ähnlichen zeilenbasierten Operation) zu senden, würden Sie tatsächlich einen Cursor verwenden.

Es gibt keine andere "zeilenbasierte" Operation, die Sie in SQL selbst ausführen würden (obwohl ich Johns Vorschlag, SSIS zu untersuchen, mag - solange Sie SQL Server Standard oder Enterprise haben). Wenn Sie jedoch Summen, Suchen oder andere Operationen ausführen und dann ein Ereignis starten, nachdem Sie die gesamte Auswahlmenge ausgeführt haben, würden Sie keinen Cursor verwenden. Nur damit Sie es wissen - Cursor werden im Allgemeinen als ein "letzter Ausweg" -Ansatz für Probleme in SQL Server betrachtet.

+0

<< Cursor werden in der Regel als "Last-Resort" -Ansatz für Probleme in SQL Server betrachtet. >> Warum? – Howiecamp

+0

Wenn Sie den Cursor verwenden, werden Sie in der Regel einen Leistungseinbruch erleiden, daher sollten Sie sie möglichst vermeiden. –

+1

Beachten Sie jedoch, dass es völlig in Ordnung ist, einen Cursor für die richtige Operation zu verwenden. Das Problem ist, dass Leute, die neu in SQL sind, oft Cursor verwenden, um Dinge zu tun, die mit Set-Operationen besser erledigt werden können (Verschieben einer Teilmenge von Datensätzen von einer Tabelle in eine andere basierend auf einigen Kriterien). Daher sind erfahrene SQL-Entwickler etwas zögerlich, sie Neulingen zu empfehlen, aus Angst, dass wir Sie auf den falschen Weg bringen. Ich würde lügen, wenn ich sagte, dass ich sie nie benutzt habe ;-) –

0

Der erste Gedanke, der mir in den Sinn kommt, wenn ich über die Ergebnismenge einer Abfrage iterieren muss, ist die Verwendung von Cursorn. Ja, es ist eine schnelle und schmutzige Art der Programmierung. Aber Cursor haben auch ihre Rückschläge - Sie verursachen Overheads und können Performance-Flaschenhals sein.

Es gibt Alternativen zur Verwendung von Cursorn. Sie können versuchen, eine temporäre Tabelle mit einer Identitätsspalte zu verwenden. Kopieren Sie Ihre Tabelle in die temporäre Tabelle und verwenden Sie eine while-Schleife, um über die Zeilen zu iterieren. Rufen Sie dann basierend auf einer Bedingung Ihre gespeicherte Prozedur auf.

Hier lesen Sie in diesem Link nach Alternativen zum Cursor - http://searchsqlserver.techtarget.com/tip/0,289483,sid87_gci1339242,00.html

prost

+0

Ich muss zugeben, dass ich keine Ahnung habe, was du sagst. Wenn Sie Ergebnisse in eine temporäre Tabelle kopieren, müssen Sie noch iterieren. Eine "While" -Schleife kann nützlich sein, während * ein Cursor verwendet wird, um * zu iterieren oder um eine Bedingung kontinuierlich zu testen, aber wie hilft es Ihnen, die Daten einer bestimmten Zeile auszuwählen und etwas zu tun (z. B. das Senden einer E-Mail)? –

+0

Ja, es ist wahr, dass eine Iteration durchgeführt werden würde, um eine temporäre Tabelle zu durchlaufen. Tatsächlich implementiert selbst SQL Server selbst Cursor, indem er eine temporäre Tabelle im Speicher erstellt. Dann gibt es Vorbehalte wie das Schließen eines Cursors, der dazu führen würde, dass Ressourcen belegt werden, bis die SQL-Verbindung geschlossen wird. Die Daten der spezifischen Zeile können mit einer Select-Abfrage in der temporären Tabelle mit einer where-Klausel in der identity-Spalte getestet werden, und die while-Schleife würde den Wert der identity-Spalte mit der rowcount vergleichen. Ich hoffe das hilft. – Arnkrishn