Wir haben eine gespeicherte Prozedur, die Benutzer manuell ausführen können, um aktualisierte Zahlen für einen Bericht zu erhalten, der den ganzen Tag über 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 abgerufen wurden. Die Ausführung dauert jedoch länger und ist für einen separaten Prozess vorgesehen 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.
Antworten:
Es sieht so aus, als gäbe es mehrere Möglichkeiten, um dies zu erreichen. Am einfachsten fand ich jedoch Martins Vorschlag , die Prozedur in einem SQL-Job einzurichten und sie mit dem asynchronen Befehl sp_start_job aus meiner gespeicherten Prozedur zu starten .
Dies funktioniert nur bei mir, da ich keine Parameter für meine gespeicherte Prozedur angeben muss.
Andere Vorschläge, die je nach Ihrer Situation funktionieren können, sind
Führen Sie den Prozess asynchron in dem Code aus, der für die Ausführung der gespeicherten Prozedur verantwortlich ist, wie von Mr.Brownstone vorgeschlagen .
Keine schlechte Idee, aber in meinem Fall wird die gespeicherte Prozedur von mehreren Stellen aufgerufen, sodass es nicht so praktisch erschien, alle diese Stellen zu finden und sicherzustellen, dass sie auch die zweite Prozedur aufrufen. Außerdem ist die zweite gespeicherte Prozedur ziemlich kritisch, und das Nichtausführen dieser Prozedur kann zu erheblichen Problemen für unser Unternehmen führen.
quelle
EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
, schlägt dies fehl, wenn der Service Broker oder SQL Agent ebenfalls nicht in Azure vorhanden ist. Ich weiß nicht, warum sich Microsoft nach anderthalb Jahrzehnten der Nachfrage weigert, etwas hinzuzufügenEXECUTE ASYNC RematerializeExpensiveCacheTable
.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 eine Beilage. Nach dem Festschreiben der Transaktion und möglicherweise noch ein paar Sekunden ruft die Aktivierung die Empfängerprozedur automatisch asynchron auf. Es ist dann nur noch nötig, die Parameter der Warteschlange zu übernehmen und die gewünschte Arbeit zu erledigen.
quelle
Diese alte Frage verdient eine umfassendere Antwort. Einige davon werden hier in anderen Antworten / Kommentaren erwähnt, andere funktionieren möglicherweise für die spezifische Situation von OP oder nicht, aber möglicherweise auch für andere, die gespeicherte Prozesse asynchron aus SQL aufrufen möchten.
Nur um ganz ausdrücklich: TSQL tut nicht (selbst) haben die Fähigkeit , asynchron andere TSQL Operationen zu starten .
Das bedeutet nicht, dass Sie noch nicht viele Optionen haben:
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 überprüfen Sie, ob sie die undokumentierte Funktion,xp_sqlagent_enum_jobs
wie in diesem hervorragenden Artikel von Gregory A. Larsen beschrieben, bereits verwendet haben). Sie müssen so viele separate Jobs erstellen, wie Sie möchten, dass parallele Prozesse ausgeführt werden, auch wenn sie denselben gespeicherten Prozess mit unterschiedlichen Parametern ausführen.sp_oacreate
undsp_oamethod
, um einen neuen Prozess zu starten, der sich gegenseitig gespeicherte Prozesse aufruft, wie in diesem Artikel beschrieben , ebenfalls von Gregory A. Larsen.Parallel_AddSql
undParallel_Execute
wie in diesem Artikel von Alan Kaplan beschrieben (nur SQL2005 +).Wenn ich es wäre, würde ich wahrscheinlich in einfacheren Szenarien mehrere SQL Agent-Jobs und in komplexeren Szenarien ein SSIS-Paket verwenden.
In Ihrem Fall klingt das Aufrufen von SQL Agent-Jobs nach einer einfachen und verwaltbaren 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 anstelle von zwei Aufgaben nacheinander keine Garantie dafür ist, dass die Aufgabe früher abgeschlossen wird. Testen Sie sorgfältig, ob es 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 Maximalgrads der Parallelität oder der Affinitätsmaske des Servers oder durch Verwenden des MAXDOP-Abfragehinweises geändert werden.
quelle
Ja, eine Methode:
quelle
sp_start_job
auf, um sie zu starten, oder erstellt Jobs nach Bedarf dynamisch, um nicht jede Minute abzufragen. In diesem Fall bedeutet die Komplexität jedoch wahrscheinlich, dass sie nicht einfacher als der Service Broker ist.sp_start_job
kehrt sofort zurück. Ich kann mich nicht erinnern, welche Berechtigungen es benötigt.Eine andere Möglichkeit wäre, die erste gespeicherte Prozedur zum Schreiben in eine Überwachungstabelle zu veranlassen, wenn sie abgeschlossen ist, und einen Auslöser in der Überwachungstabelle zu platzieren, der die zweite gespeicherte Prozedur startet, wenn in die Überwachungstabelle geschrieben wird. Es muss nicht ständig abgefragt werden und es ist kein zusätzlicher SQL Server-Agent-Job erforderlich.
quelle
INSERT
orUPDATE
und nicht asynchron ausgeführt. Martin hat also Recht, dass die erste Prozedur immer noch darauf wartet, bis die zweite Prozedur beendet ist, um zurückzukehren.