Tengo varios trabajos del Agente SQL Server que deberían ejecutarse secuencialmente. Para mantener una buena visión general de los trabajos que deberían ejecutarse, he creado un trabajo principal que llama a los otros trabajos con una llamada a EXEC msdb.dbo.sp_start_job N'TEST1'
. Los sp_start_job
acabados de forma instantánea (paso de trabajo 1), pero entonces yo quiero que mi trabajo principal que esperar hasta que el trabajo TEST1
haya terminado antes de llamar al siguiente trabajo.
Así que escribí este pequeño script que comienza a ejecutarse justo después de que se llama al trabajo (Paso 2 del trabajo), y obliga al trabajo principal a esperar hasta que el trabajo secundario haya finalizado:
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;
Esto funciona bastante bien. Pero tuve la sensación de WHILE 1 = 1
que deberían ser posibles soluciones más inteligentes y / o más seguras ( ?).
Tengo curiosidad por las siguientes cosas, espero que me puedan proporcionar algunas ideas:
- ¿Cuáles son los problemas con este enfoque?
- ¿Puedes sugerir una mejor manera de hacer esto?
(Publiqué esta pregunta en StackOverflow primero, porque me estaba enfocando en mejorar el código. Todavía es válido. Pero supongo que la gente aquí en general tendrá cosas más inteligentes que decir sobre por qué no debería intentar hacer esto de la manera en que yo ' lo estoy haciendo ahora, o proporciono buenas alternativas.)
EDITAR (25 de julio)
Aparentemente, no hay demasiados errores con mi script, de acuerdo con el bajo número de respuestas que señalan problemas con él :-) La alternativa a este tipo de scripting parece ser utilizar una herramienta diseñada para estos tareas (como el Administrador de eventos de SQL Sentry o ...), o escribir dicha herramienta usted mismo. No compraremos una herramienta así en mi compañía actual, así que por ahora me quedaré con el guión.
fuente
Respuestas:
Descargo de responsabilidad: trabajo para SQL Sentry.
Nuestro producto SQL Sentry Event Manager tiene una instalación creada exactamente para esto: encadenar trabajos y organizarlos en varios pedidos de flujo de trabajo.
Comencé a usar SQL Sentry hace años, antes de unirme a la compañía, para hacer exactamente esto. Lo que quería era una forma de iniciar un trabajo de restauración en nuestro servidor de prueba inmediatamente después de que la copia de seguridad en producción hubiera terminado.
Lo que había implementado originalmente era solo un búfer sustancial entre la hora de inicio del trabajo de copia de seguridad y la hora de inicio de la restauración. Esto no era exactamente infalible; Como los tiempos de respaldo variaban, el búfer a menudo nos dejaba un tiempo perdido donde la restauración no había comenzado a pesar de que podría haberlo hecho. Y ocasionalmente el búfer no era suficiente.
Lo que implementé a continuación fue similar a lo que usted tiene: escribí un trabajo en el servidor de prueba que comenzó poco después de la copia de seguridad programada, y seguí sondeando para ver cuándo finalizó el trabajo. Posteriormente se modificó para tener un segundo paso en el trabajo de copia de seguridad que actualizó una tabla en el servidor de prueba. No es muy diferente, excepto que el trabajo de restauración solo tenía que mirar una tabla localmente en lugar de monitorear el historial de trabajo de forma remota. Pensando en esto, podría haber sido un desencadenante en esa tabla que llamó
sp_start_job
para que el trabajo no tuviera que ejecutarse cada n minutos (o estar programado)La solución final fue encadenar los trabajos juntos ... cuando finaliza la copia de seguridad en el servidor A, Event Manager inicia el trabajo de restauración en el servidor B. Y si hubo un tercer trabajo y un cuarto trabajo, o lógica condicional basada en qué hacer cuando un trabajo falla vs. tiene éxito, etc., todo esto puede explicarse. El diseñador de flujo de trabajo le recordará un poco de SSIS:
La mecánica subyacente de lo que estoy describiendo no es la cirugía con cohetes, por supuesto. Podría escribir este tipo de envoltura de encadenamiento usted mismo si se sentara y lo hiciera. Simplemente proporcionándole una alternativa donde no tiene que hacerlo.
fuente
El principal problema con su enfoque es que tiene que dar vueltas continuamente hasta que ocurra algo (lo que podría ser mucho tiempo o incluso nunca) y eso no se siente bien. Por eso supongo que estás haciendo la pregunta.
Entonces, ¿qué tal usar un enfoque basado en datos para su problema? Por ejemplo, cree una tabla de 'auditoría' en la que cada trabajo escribe cuando comienza y termina:
Cree una tabla de 'procesamiento' que enumere todos los trabajos y el orden en que deben ejecutarse:
Cree un activador de inserción en la tabla de auditoría, de modo que cuando se complete un trabajo y se inserte el registro de auditoría, el activador consulta la tabla de procesamiento para el siguiente trabajo (por orden de ejecución) y luego lo inicia.
Los beneficios de este enfoque son:
HTH
fuente