Tenemos un procedimiento almacenado que los usuarios pueden ejecutar manualmente para obtener algunos números actualizados para un informe que se usa constantemente durante todo el día.
Tengo un segundo procedimiento almacenado que debe ejecutarse después de que se ejecute el primer procedimiento almacenado, ya que se basa en los números obtenidos de este primer procedimiento almacenado, sin embargo, toma más tiempo ejecutarlo y es para un proceso separado, por lo que no quiero hacer que el usuario espere mientras se ejecuta este segundo procedimiento almacenado.
¿Hay alguna manera de hacer que un procedimiento almacenado comience un segundo procedimiento almacenado y regrese inmediatamente sin esperar los resultados?
Estoy usando SQL Server 2005.
Respuestas:
Parece que hay varias formas de lograr esto, pero descubrí que la forma más simple fue la sugerencia de Martin de configurar el procedimiento en un trabajo SQL y comenzarlo usando el comando asincrónico sp_start_job de mi procedimiento almacenado.
Esto solo funciona para mí porque no necesito especificar ningún parámetro para mi procedimiento almacenado.
Otras sugerencias que pueden funcionar dependiendo de su situación son
Ejecutar el proceso de forma asincrónica en el código responsable de ejecutar el procedimiento almacenado, como sugirió Mr.Brownstone .
No es una mala idea, sin embargo, en mi caso, el procedimiento almacenado se llama desde varios lugares, por lo que encontrar todos esos lugares y asegurarse de que también llamen al segundo procedimiento no parecía tan práctico. Además, el segundo procedimiento almacenado es bastante crítico, y olvidar ejecutarlo podría causar algunos problemas importantes para nuestra empresa.
fuente
EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Also, ni Service Broker ni Sql Agent existen en Azure. No sé por qué Microsoft, después de una década y media de personas preguntando, se niega a agregarEXECUTE ASYNC RematerializeExpensiveCacheTable
.Puede usar Service Broker junto con la activación en la cola. Con eso, puede publicar los parámetros para la llamada al procedimiento en la cola. Eso lleva casi tanto tiempo como un inserto. Una vez que se confirma la transacción y potencialmente unos segundos más, la activación llamará automáticamente al procedimiento del receptor de forma asincrónica. Simplemente debe tomar los parámetros de la cola y hacer el trabajo deseado.
fuente
Esta vieja pregunta merece una respuesta más completa. Algunos de estos se mencionan en otras respuestas / comentarios aquí, otros pueden o no funcionar para la situación específica de OP, pero pueden funcionar para otros que buscan llamar a los procedimientos almacenados asincrónicamente desde SQL.
Solo para ser totalmente explícito: TSQL no tiene (por sí mismo) la capacidad de lanzar otras operaciones TSQL de forma asincrónica .
Eso no significa que todavía no tenga muchas opciones:
sp_start_job
. Si necesita monitorear su progreso programáticamente, solo asegúrese de que cada trabajo actualice una tabla JOB_PROGRESS personalizada (o puede verificar si han terminado de usar la función no documentadaxp_sqlagent_enum_jobs
como se describe en este excelente artículo de Gregory A. Larsen). Debe crear tantos trabajos separados como desee que se ejecuten los procesos paralelos, incluso si están ejecutando el mismo proceso almacenado con diferentes parámetros.sp_oacreate
ysp_oamethod
para iniciar un nuevo proceso que se llame entre sí a un proceso almacenado como se describe en este artículo , también por Gregory A. Larsen.Parallel_AddSql
yParallel_Execute
como se describe en este artículo por Alan Kaplan (solo SQL2005 +).Si fuera yo, probablemente usaría múltiples trabajos de Agente SQL en escenarios más simples y un paquete SSIS en escenarios más complejos.
En su caso, llamar a trabajos de Agente SQL suena como una opción simple y manejable.
Un comentario final : SQL ya intenta paralelizar operaciones individuales siempre que puede *. Esto significa que ejecutar 2 tareas al mismo tiempo en lugar de una tras otra no garantiza que terminará antes. Pruebe cuidadosamente para ver si realmente mejora algo o no.
Tuvimos un desarrollador que creó un paquete DTS para ejecutar 8 tareas al mismo tiempo. Desafortunadamente, solo era un servidor de 4 CPU :)
* Asumiendo la configuración predeterminada. Esto se puede modificar alterando el Grado máximo de paralelismo o la Máscara de afinidad del servidor, o utilizando la sugerencia de consulta MAXDOP.
fuente
Sí, un método:
fuente
sp_start_job
para iniciarlo o crear trabajos según sea necesario dinámicamente para evitar sondeos cada minuto, pero la complejidad para ese caso probablemente significa que no será más simple que el intermediario de servicios.sp_start_job
vuelve de inmediato. Sin embargo, no puedo recordar qué permisos necesita.Otra posibilidad sería obtener el primer procedimiento almacenado para escribir en una tabla de auditoría cuando se complete y colocar un disparador en la tabla de auditoría que inicie el segundo procedimiento almacenado cuando se escriba en la tabla de auditoría. No es necesario sondear continuamente y no es necesario un trabajo adicional del Agente SQL Server.
fuente
INSERT
oUPDATE
, no de forma asíncrona, por lo que Martin tiene razón en que el primer procedimiento todavía terminaría esperando hasta que el segundo procedimiento termine de regresar.