it-swarm.com.de

Kann ich eine gespeicherte Prozedur starten und sofort zurückkehren, ohne darauf zu warten, dass sie abgeschlossen ist?

Wir haben eine gespeicherte Prozedur, die Benutzer manuell ausführen können, um einige aktualisierte Nummern für einen Bericht zu erhalten, der den ganzen Tag über ständig verwendet wird.

Ich habe eine zweite gespeicherte Prozedur, die ausgeführt werden sollte, nachdem die erste gespeicherte Prozedur ausgeführt wurde, da sie auf den Zahlen basiert, die von dieser ersten gespeicherten Prozedur erhalten wurden. Die Ausführung dauert jedoch länger und ist für einen separaten Prozess vorgesehen, sodass ich dies nicht möchte Lassen Sie den Benutzer warten, während diese zweite gespeicherte Prozedur ausgeführt wird.

Gibt es eine Möglichkeit, eine gespeicherte Prozedur eine zweite gespeicherte Prozedur starten zu lassen und sofort zurückzukehren, ohne auf Ergebnisse zu warten?

Ich verwende SQL Server 2005.

41
Rachel

Es sieht so aus, als gäbe es mehrere Möglichkeiten, dies zu erreichen, aber ich fand, dass der einfachste Weg Martins Vorschlag war, die Prozedur in einem SQL-Job einzurichten und mit dem asynchronen sp_start_job zu starten = Befehl von meiner gespeicherten Prozedur.

EXEC msdb.dbo.sp_start_job @job_name='Run2ndStoredProcedure'

Dies funktioniert nur bei mir, da ich für meine gespeicherte Prozedur keine Parameter angeben muss.

Andere Vorschläge, die je nach Ihrer Situation funktionieren können, sind

  • Verwenden Sie SQL Service Broker wie Martin und Sebastian vorschlagen. Dies ist wahrscheinlich der beste Vorschlag, wenn Ihnen die Komplexität der Einrichtung und des Lernens der Funktionsweise nichts ausmacht.
  • Ausführen des Prozesses asynchron in dem Code, der für die Ausführung der gespeicherten Prozedur verantwortlich ist, wie z. B. Mr.Brownstone vorgeschlagen .

    Keine schlechte Idee, aber in meinem Fall wird die gespeicherte Prozedur von mehreren Stellen aus aufgerufen. Daher schien es nicht so praktisch, alle diese Stellen zu finden und sicherzustellen, dass auch die zweite Prozedur aufgerufen wird. Außerdem ist die zweite gespeicherte Prozedur ziemlich kritisch, und das Vergessen, sie auszuführen, kann einige große Probleme für unser Unternehmen verursachen.

  • Lassen Sie die erste Prozedur ein Flag setzen und einen wiederkehrenden Job einrichten, um nach diesem Flag zu suchen und auszuführen, wenn es gesetzt ist, wie Jimbo schlug vor . Ich bin kein großer Fan von Jobs, die ständig ausgeführt werden und alle paar Minuten nach Änderungen suchen, aber es ist sicherlich eine Option, die je nach Ihrer Situation in Betracht gezogen werden sollte.
28
Rachel

Diese alte Frage verdient eine umfassendere Antwort. Einige davon werden in anderen Antworten/Kommentaren hier erwähnt, andere funktionieren möglicherweise nicht für die spezifische Situation von OP, aber möglicherweise auch für andere, die gespeicherte Prozesse asynchron aus SQL aufrufen möchten.

Nur um ganz explizit zu sein: TSQL hat nicht (für sich) die Möglichkeit, andere TSQL-Operationen asynchron zu starten .

Das bedeutet nicht, dass Sie noch nicht viele Optionen haben:

  • SQL Agent-Jobs : Erstellen Sie mehrere SQL-Jobs und planen Sie entweder die Ausführung zum gewünschten Zeitpunkt oder starten Sie sie asynchron von einem gespeicherten "Master Control" -Prozess mit sp_start_job. Wenn Sie ihren Fortschritt programmgesteuert überwachen müssen, stellen Sie einfach sicher, dass die Jobs jeweils eine benutzerdefinierte JOB_PROGRESS-Tabelle aktualisieren (oder Sie können überprüfen, ob sie noch fertig sind, indem Sie die undokumentierte Funktion xp_sqlagent_enum_jobs Verwenden, wie in this) beschrieben ausgezeichneter Artikel von Gregory A. Larsen). Sie müssen so viele separate Jobs erstellen, wie parallele Prozesse ausgeführt werden sollen, auch wenn sie denselben gespeicherten Prozess mit unterschiedlichen Parametern ausführen.
  • SSIS-Paket : Erstellen Sie für kompliziertere asynchrone Szenarien ein SSIS-Paket mit einem einfachen Verzweigungs-Taskflow. SSIS startet diese Aufgaben in einzelnen Spids, die SQL parallel ausführt. Rufen Sie das SSIS-Paket von einem SQL-Agentenjob aus auf.
  • Benutzerdefinierte Anwendung : Schreiben Sie eine einfache benutzerdefinierte Anwendung in der Sprache Ihrer Wahl (C #, Powershell usw.) mit den von dieser Sprache bereitgestellten asynchronen Methoden. Rufen Sie einen gespeicherten SQL-Prozess für jeden Anwendungsthread auf.
  • OLE-Automatisierung : Verwenden Sie in SQL sp_oacreate Und sp_oamethod, Um einen neuen Prozess zu starten, der sich gegenseitig wie beschrieben speichert in dieser Artikel , ebenfalls von Gregory A. Larsen.
  • Service Broker : Sehen Sie sich die Verwendung von Service Broker an, a gutes Beispiel für die asynchrone Ausführung in diesem Artikel .
  • CLR Parallel Execution : Verwenden Sie die CLR-Befehle Parallel_AddSql Und Parallel_Execute Wie in dieser Artikel beschrieben = von Alan Kaplan (nur SQL2005 +).
  • Geplante Windows-Aufgaben : Der Vollständigkeit halber aufgeführt, aber ich bin kein Fan dieser Option.

Wenn ich es wäre, würde ich wahrscheinlich mehrere SQL Agent-Jobs in einfacheren Szenarien und ein SSIS-Paket in komplexeren Szenarien verwenden.

In Ihrem Fall klingt das Aufrufen von SQL Agent-Jobs nach einer einfachen und überschaubaren Wahl.

Ein letzter Kommentar : SQL versucht bereits, einzelne Operationen zu parallelisieren, wann immer dies möglich ist *. Dies bedeutet, dass das gleichzeitige Ausführen von zwei Aufgaben statt nacheinander keine Garantie dafür ist, dass sie früher abgeschlossen werden. Testen Sie sorgfältig, ob sich tatsächlich etwas verbessert oder nicht.

Wir hatten einen Entwickler, der ein DTS Paket) erstellt hat, um 8 Aufgaben gleichzeitig auszuführen. Leider war es nur ein 4-CPU-Server :)

* Vorausgesetzt, Standardeinstellungen. Dies kann durch Ändern des maximalen Parallelitätsgrads oder der Affinitätsmaske des Servers oder mithilfe des MAXDOP-Abfragehinweises geändert werden.

8
BradC

Sie können den Service Broker zusammen mit der Aktivierung in der Warteschlange verwenden. Damit können Sie die Parameter für den Prozeduraufruf in die Warteschlange stellen. Das dauert ungefähr so ​​lange wie ein Einsatz. Nach dem Festschreiben der Transaktion und möglicherweise noch einige Sekunden würde die Aktivierung die Empfängerprozedur automatisch asynchron aufrufen. Es muss nicht nur die Parameter der Warteschlange übernehmen und die gewünschte Arbeit erledigen.

8
Sebastian Meine

Ja, eine Methode:

  1. Wenn die erste gespeicherte Prozedur abgeschlossen ist, wird ein Datensatz mit allen Informationen eingefügt, die für die Ausführung der zweiten gespeicherten Prozedur erforderlich sind
  2. Die zweite gespeicherte Prozedur wird als Job ausgeführt, jede Minute oder zu welcher Zeit Sie sich entscheiden
  3. Es sucht nach eingefügten Datensätzen, führt seinen Prozess durch und markiert den Datensatz als vollständig
6
Jimbo

Eine andere Möglichkeit wäre, die erste gespeicherte Prozedur nach Abschluss in eine Prüftabelle schreiben zu lassen und einen Auslöser für die Prüftabelle zu platzieren, der die zweite gespeicherte Prozedur startet, wenn in die Prüftabelle geschrieben wird. Keine ständige Abfrage und kein zusätzlicher SQL Server-Agent-Job erforderlich.

1
paco