J'ai plusieurs travaux d'agent SQL Server qui devraient s'exécuter de manière séquentielle. Pour garder une bonne vue d'ensemble des travaux qui devraient s'exécuter, j'ai créé un travail principal qui appelle les autres travaux avec un appel à EXEC msdb.dbo.sp_start_job N'TEST1'
. Le se sp_start_job
termine instantanément (Étape 1 du travail), mais je veux que mon travail principal attende la fin du travail TEST1
avant d'appeler le prochain travail.
J'ai donc écrit ce petit script qui commence à s'exécuter juste après l'appel du travail (étape 2 du travail) et force le travail principal à attendre la fin du sous-travail:
WHILE 1 = 1
BEGIN
WAITFOR DELAY '00:05:00.000';
SELECT *
INTO #jobs
FROM OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
@execution_status = 0, @job_aspect = N''JOB''');
IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
BEGIN
BREAK
END;
DROP TABLE #jobs;
END;
Cela fonctionne assez bien. Mais j'ai l'impression que des WHILE 1 = 1
solutions plus intelligentes et / ou plus sûres ( ?) Devraient être possibles.
Je suis curieux de savoir ce qui suit, j'espère que vous pourrez me fournir quelques informations:
- Quels sont les problèmes avec cette approche?
- Pouvez-vous suggérer une meilleure façon de procéder?
(J'ai d'abord posé cette question sur StackOverflow , parce que je me concentrais sur l'amélioration du code. Toujours valide. Mais je suppose que les gens ici auront en général des choses plus intelligentes à dire sur les raisons pour lesquelles je ne devrais pas essayer de le faire comme je le fais. Je le fais maintenant ou offre de bonnes alternatives.)
EDIT (25 juillet)
Apparemment, il n'y a pas trop de problème avec mon script, selon le faible nombre de réponses signalant des problèmes avec celui-ci :-) L'alternative à ce type de script semble être d'utiliser un outil conçu pour ces (comme SQL Sentry Event Manager ou ...) - ou pour écrire un tel outil vous-même. Nous n'achèterons pas un tel outil dans mon entreprise actuelle, donc pour l'instant je vais simplement m'en tenir au script.
la source
Réponses:
Avertissement: je travaille pour SQL Sentry.
Notre produit SQL Sentry Event Manager a une fonctionnalité conçue spécialement pour cela: pour enchaîner les tâches et les organiser dans divers ordres de workflow.
J'ai commencé à utiliser SQL Sentry il y a des années, avant de rejoindre l'entreprise, pour faire exactement cela. Ce que je voulais, c'était un moyen de démarrer un travail de restauration sur notre serveur de test immédiatement après la fin de la sauvegarde en production.
Ce que j'avais initialement implémenté n'était qu'un tampon substantiel entre l'heure de début du travail de sauvegarde et l'heure de début de la restauration. Ce n'était pas vraiment infaillible; comme les temps de sauvegarde variaient, le tampon nous laissait souvent du temps perdu où une restauration n'avait pas commencé même si elle aurait pu. Et parfois, le tampon n'était pas suffisant.
Ce que j'ai implémenté ensuite était similaire à ce que vous avez - j'ai écrit un travail sur le serveur de test qui a commencé peu de temps après la sauvegarde planifiée et j'ai continué à interroger pour voir quand le travail était terminé. Cela a été modifié par la suite pour n'avoir qu'une deuxième étape dans le travail de sauvegarde qui a mis à jour une table sur le serveur de test. Pas vraiment très différent, sauf que le travail de restauration n'avait qu'à regarder une table localement au lieu de surveiller l'historique des travaux à distance. En y repensant, cela aurait pu être un déclencheur sur cette table qui a appelé
sp_start_job
afin que le travail n'ait pas à s'exécuter toutes les n minutes (ou à être planifié du tout).La solution finale était de chaîner les travaux ensemble ... lorsque la sauvegarde sur le serveur A se termine, Event Manager démarre le travail de restauration sur le serveur B. Et s'il y avait un troisième travail et un quatrième travail, ou une logique conditionnelle basée sur ce qu'il faut faire quand un travail échoue vs réussit, etc., tout cela peut être expliqué. Le concepteur de workflow vous rappellera un peu SSIS:
La mécanique sous-jacente de ce que je décris n'est pas la chirurgie à la fusée, bien sûr. Vous pouvez écrire vous-même ce type d'encapsuleur de chaînage si vous vous asseyez et le faites. Vous offrant simplement une alternative là où vous n'avez pas à le faire.
la source
Le principal problème avec votre approche est que vous devez continuellement boucler jusqu'à ce que quelque chose se produise (ce qui pourrait être terriblement long ou même jamais) et cela ne vous semble pas tout à fait correct. C'est pourquoi je suppose que vous posez la question.
Alors, que diriez-vous d'utiliser une approche basée sur les données pour votre problème? Par exemple, créez une table «d'audit» dans laquelle chaque travail écrit au début et à la fin:
Créez une table de «traitement» qui répertorie tous les travaux et l'ordre dans lequel ils doivent être exécutés:
Créez un déclencheur d'insertion sur la table d'audit, de sorte que lorsqu'un travail se termine et que l'enregistrement d'audit soit inséré, le déclencheur interroge la table de traitement pour le travail suivant (par ordre d'exécution), puis le lance.
Les avantages de cette approche sont:
HTH
la source