web-dev-qa-db-fra.com

Puis-je lancer une procédure stockée et revenir immédiatement sans attendre qu'elle se termine?

Nous avons une procédure stockée que les utilisateurs peuvent exécuter manuellement pour obtenir des numéros mis à jour pour un rapport qui est utilisé en permanence tout au long de la journée.

J'ai une deuxième procédure stockée qui doit être exécutée après l'exécution de 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, mais elle prend plus de temps à exécuter et concerne un processus distinct, donc je ne veux pas faire attendre l'utilisateur pendant l'exécution de cette 2e procédure stockée.

Existe-t-il un moyen pour qu'une procédure stockée démarre une deuxième procédure stockée et revienne immédiatement sans attendre les résultats?

J'utilise SQL Server 2005.

41
Rachel

Il semble qu'il existe plusieurs façons d'accomplir cela, mais j'ai trouvé que la manière la plus simple était suggestion de Martin de configurer la procédure dans un travail SQL et de la démarrer en utilisant l'asynchrone sp_start_job = commande de ma procédure stockée.

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

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

  • Utiliser le SQL Service Broker comme Martin et Sebastian suggèrent. C'est probablement la meilleure suggestion si cela ne vous dérange pas de la complexité de sa configuration et de son fonctionnement.
  • Exécuter le processus de manière asynchrone dans le code responsable de l'exécution de la procédure stockée, comme M.Brownstone a suggéré .

    Ce n'est pas une mauvaise idée, mais dans mon cas, la procédure stockée est appelée à partir de plusieurs endroits, donc trouver tous ces endroits et s'assurer qu'ils appellent la 2ème procédure ne semblait pas aussi pratique. De plus, la 2e procédure stockée est assez critique et oublier de l'exécuter pourrait causer des problèmes majeurs à notre entreprise.

  • Faites en sorte que la 1ère procédure définisse un indicateur, et configurez un travail récurrent pour vérifier cet indicateur et exécuter si son ensemble, comme Jimbo suggéré . Je ne suis pas un grand fan des travaux qui s'exécutent constamment et vérifient les changements toutes les quelques minutes, mais c'est certainement une option qui mérite d'être envisagée en fonction de votre situation.
28
Rachel

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 non fonctionner pour la situation spécifique d'OP, mais peuvent fonctionner pour d'autres qui recherchent des procs stockés de manière asynchrone à partir de SQL.

Juste pour être totalement explicite: TSQL ne pas (par lui-même) a la possibilité de lancer d'autres opérations TSQL de manière asynchrone .

Cela ne signifie pas que vous n'avez toujours pas beaucoup d'options:

  • Tâches de l'Agent SQL : créez plusieurs tâches SQL et planifiez-les pour qu'elles s'exécutent à l'heure souhaitée, ou lancez-les de manière asynchrone à partir d'un processus stocké de "contrôle maître" en utilisant sp_start_job. Si vous avez besoin de surveiller leur progression par programme, assurez-vous simplement que les travaux mettent chacun à jour une table JOB_PROGRESS personnalisée (ou vous pouvez vérifier s'ils n'ont pas encore utilisé la fonction non documentée xp_sqlagent_enum_jobs comme décrit dans cet excellent article par Gregory A. Larsen). Vous devez créer autant de tâches distinctes que vous voulez que les processus parallèles s'exécutent, même s'ils exécutent le même proc stocké avec des paramètres différents.
  • Package SSIS : pour des scénarios asynchrones plus complexes, créez un package SSIS avec un flux de tâches de branchement simple. SSIS lancera ces tâches dans des spids individuels, que SQL exécutera en parallèle. Appelez le package SSIS à partir d'un travail d'agent SQL.
  • Application personnalisée : Écrivez une application personnalisée simple dans la langue de votre choix (C #, Powershell, etc.), en utilisant les méthodes asynchrones fournies par cette langue. Appelez un proc stocké SQL sur chaque thread d'application.
  • OLE Automation : dans SQL, utilisez sp_oacreate et sp_oamethod pour lancer un nouveau processus s'appelant les uns les autres, comme décrit dans cet article , également par Gregory A. Larsen.
  • Service Broker : essayez d'utiliser Service Broker , un bon exemple d'exécution asynchrone dans cet article .
  • Exécution parallèle CLR : utilisez les commandes CLR Parallel_AddSql et Parallel_Execute comme décrit dans cet article par Alan Kaplan (SQL2005 + uniquement).
  • Tâches Windows planifiées : répertoriées pour être complètes, mais je ne suis pas fan de cette option.

Si c'était moi, j'utiliserais probablement plusieurs tâches d'agent SQL dans des scénarios plus simples et un package SSIS dans des scénarios plus complexes.

Dans votre cas, appeler des travaux 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 au lieu l'une de l'autre ne garantit pas qu'elle se terminera plus tôt. Testez soigneusement pour voir si cela améliore réellement quelque chose ou non.

Nous avons eu un développeur qui a créé un package DTS pour exécuter 8 tâches en même temps. Malheureusement, ce n'était qu'un serveur à 4 CPU :)

* En supposant les paramètres par défaut. Cela peut être modifié en modifiant le degré maximal de parallélisme ou le masque d'affinité du serveur, ou en utilisant l'indicateur de requête MAXDOP.

8
BradC

Vous pouvez utiliser Service Broker avec l'activation dans la file d'attente. Avec cela, vous pouvez publier les paramètres de l'appel de procédure dans la file d'attente. Cela prend environ autant de temps qu'un encart. Une fois la transaction validée et potentiellement quelques secondes de plus, l'activation appelle automatiquement la procédure de réception de manière asynchrone. Il suffit de prendre les paramètres de la file d'attente et de faire le travail souhaité.

8
Sebastian Meine

Oui, une méthode:

  1. Lorsque la 1ère procédure stockée est terminée, il insère un enregistrement avec toutes les informations nécessaires à l'exécution de la deuxième procédure stockée
  2. La deuxième procédure stockée s'exécute comme un travail, chaque minute ou à quelle heure vous décidez
  3. Il vérifie les enregistrements insérés, effectue son processus et marque l'enregistrement comme terminé
6
Jimbo

Une autre possibilité serait d'obtenir la première procédure stockée pour écrire dans une table d'audit lorsqu'elle se termine et de placer un déclencheur sur la table d'audit qui lance la 2ème procédure stockée lorsque la table d'audit est écrite. Pas besoin d'interroger en continu et pas besoin d'un travail supplémentaire de l'Agent SQL Server.

1
paco