Nous avons une procédure stockée que les utilisateurs peuvent exécuter manuellement pour obtenir des numéros mis à jour pour un rapport utilisé constamment tout au long de la journée.
J'ai une deuxième procédure stockée qui doit être exécutée après la première procédure stockée, car elle est basée sur les nombres obtenus à partir de cette première procédure stockée. Toutefois, son exécution est plus longue et concerne un processus séparé. Je ne souhaite donc pas faire patienter l'utilisateur pendant l'exécution de cette deuxième procédure stockée.
Existe-t-il un moyen de faire en sorte qu'une procédure stockée démarre une seconde procédure stockée et revienne immédiatement sans attendre les résultats?
J'utilise SQL Server 2005.
Réponses:
Il semble y avoir de nombreuses façons d’y parvenir, mais j’ai trouvé que le moyen le plus simple était de suggérer à Martin d’établir la procédure dans un travail SQL et de le démarrer à l’aide de la commande asynchrone sp_start_job de ma procédure stockée.
Cela ne fonctionne que pour moi car je n'ai pas besoin de spécifier de paramètres pour ma procédure stockée.
D’autres suggestions qui peuvent fonctionner en fonction de votre situation sont
Exécuter le processus de manière asynchrone dans le code responsable de l’exécution de la procédure stockée, comme l’ a suggéré M.Brownstone .
Ce n'est pas une mauvaise idée, mais dans mon cas, la procédure stockée est appelée depuis plusieurs endroits. Trouver tous ces endroits et veiller à ce qu'ils appellent la deuxième procédure ne semblait pas très pratique. En outre, la deuxième procédure stockée est assez critique, et l’oubli de son exécution pourrait entraîner des problèmes majeurs pour notre société.
la source
EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Service ni Broker, ni SQL Agent n'existent également sur Azure. J'ignore pourquoi, après une quinzaine d'années, Microsoft refuse d'ajouterEXECUTE ASYNC RematerializeExpensiveCacheTable
.Vous pouvez utiliser Service Broker avec l'activation de la file d'attente. Avec cela, vous pouvez enregistrer les paramètres de l'appel de procédure dans la file d'attente. Cela prend à peu près autant de temps qu’un insert. Une fois la transaction validée et éventuellement quelques secondes de plus, l'activation appelle automatiquement la procédure de destinataire de manière asynchrone. Il ne reste plus qu’à prendre les paramètres de la file d’attente et à effectuer le travail souhaité.
la source
Cette vieille question mérite une réponse plus complète. Certains d'entre eux sont mentionnés dans d'autres réponses / commentaires ici, d'autres peuvent ou ne peuvent pas fonctionner pour la situation spécifique de OP, mais peuvent fonctionner pour d'autres recherchant des appels stockés de manière asynchrone à partir de SQL.
Pour être tout à fait explicite, TSQL n’a pas (à lui seul) la capacité de lancer d’autres opérations TSQL de manière asynchrone .
Cela ne signifie pas que vous n'avez pas encore beaucoup d'options:
sp_start_job
. Si vous devez surveiller leur progression par programme, assurez-vous simplement que les travaux mettent à jour une table JOB_PROGRESS personnalisée (ou vous pouvez vérifier s'ils ont déjà fini d'utiliser la fonction non documentéexp_sqlagent_enum_jobs
décrite dans cet excellent article. de Gregory A. Larsen). Vous devez créer autant de travaux distincts que vous souhaitez que des processus parallèles soient exécutés, même s'ils exécutent le même processus stocké avec des paramètres différents.sp_oacreate
etsp_oamethod
pour lancer un nouveau processus s'appelant un processus enregistré, comme décrit dans cet article , également par Gregory A. Larsen.Parallel_AddSql
etParallel_Execute
comme décrit dans cet article par Alan Kaplan (SQL2005 + uniquement).Si c'était moi, j'utiliserais probablement plusieurs jobs d'agent SQL dans des scénarios plus simples et un package SSIS dans des scénarios plus complexes.
Dans votre cas, appeler des tâches SQL Agent semble être un choix simple et gérable.
Un dernier commentaire : SQL tente déjà de paralléliser des opérations individuelles chaque fois qu'il le peut *. Cela signifie que l'exécution de 2 tâches en même temps plutôt que les unes après les autres ne garantit en aucun cas qu'elle se terminera plus tôt. Testez soigneusement pour voir si cela améliore réellement quelque chose ou non.
Un développeur a créé un package DTS pour exécuter 8 tâches simultanément. Malheureusement, ce n'était qu'un serveur à 4 processeurs :)
* En supposant les paramètres par défaut. Cela peut être modifié en modifiant le degré maximum de parallélisme ou le masque d'affinité du serveur ou en utilisant l'indicateur de requête MAXDOP.
la source
sp_start_job
, comme je le décris dans mon premier point (étant donné qu'il n'y a pas de type d'étape de travail intégré consistant à "démarrer un autre travail"). Mais je pense que vous avez raison de dire que les statuts de travail individuels ne sont pas transmis au maître; vous devez interroger le statut échec / succès individuellement.Oui, une méthode:
la source
sp_start_job
pour la démarrer ou créer des tâches selon les besoins de manière dynamique pour éviter toute interrogation, mais la complexité de ce cas signifie probablement que ce ne sera pas plus simple que service broker.sp_start_job
revient immédiatement. Je ne me souviens plus des autorisations dont il a besoin.Une autre possibilité serait d’écrire la 1ère procédure stockée dans une table d’audit une fois celle-ci terminée et de placer un déclencheur sur la table d’audit qui lance la 2e procédure stockée lors de l’écriture de la table d’audit. Pas besoin d'interroger en permanence et pas besoin d'un travail supplémentaire de l'Agent SQL Server.
la source
INSERT
orUPDATE
, et non de manière asynchrone. Martin a donc raison de dire que la 1ère procédure finira par attendre que la 2e procédure se termine.