Eu tenho vários trabalhos do SQL Server Agent que devem ser executados sequencialmente. Para manter uma boa visão geral dos trabalhos que devem ser executados, criei um trabalho principal que chama os outros trabalhos com uma chamada para EXEC msdb.dbo.sp_start_job N'TEST1'
. A sp_start_job
finalização é instantânea (Etapa 1 do trabalho), mas quero que meu trabalho principal aguarde até que o trabalho TEST1
termine antes de chamar o próximo trabalho.
Então, eu escrevi este pequeno script que começa a ser executado logo após o trabalho ser chamado (Etapa 2 do trabalho) e força o trabalho principal a esperar até que o sub-trabalho termine:
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;
Isso funciona bem o suficiente. Mas tive a sensação de que WHILE 1 = 1
soluções mais inteligentes e / ou mais seguras ( ?) Devem ser possíveis.
Estou curioso sobre o seguinte, espero que você possa me fornecer algumas idéias:
- Quais são os problemas com essa abordagem?
- Você pode sugerir uma maneira melhor de fazer isso?
(Postei essa pergunta no StackOverflow primeiro, porque estava focado na melhoria do código. Ainda válido. Mas meu palpite é que as pessoas aqui em geral têm coisas mais inteligentes a dizer sobre por que não devo tentar fazer isso da maneira que eu faço '' estou fazendo isso agora ou forneça boas alternativas.)
EDIT (25 de julho)
Aparentemente, não há muito errado com o meu script, de acordo com o baixo número de respostas que apontam problemas com ele :-) A alternativa para esse tipo de script parece ser o uso de uma ferramenta projetada para esses scripts. tarefas (como SQL Sentry Event Manager ou ...) - ou para escrever você mesmo essa ferramenta. Não compraremos essa ferramenta na minha empresa atual, então, por enquanto, continuarei com o script.
fonte
Respostas:
Disclaimer: Eu trabalho para o SQL Sentry.
Nosso produto SQL Sentry Event Manager possui um recurso criado exatamente para isso: encadear tarefas e organizá-las em várias ordens de fluxo de trabalho.
Comecei a usar o SQL Sentry anos atrás, antes de ingressar na empresa, para fazer exatamente isso. O que eu queria era uma maneira de iniciar um trabalho de restauração em nosso servidor de teste imediatamente após a conclusão do backup em produção.
O que eu havia implementado originalmente era apenas um buffer substancial entre o horário de início da tarefa de backup e o horário de início da restauração. Isso não era exatamente à prova de falhas; como os tempos de backup variavam, o buffer geralmente nos deixava com tempo perdido, onde uma restauração não havia sido iniciada mesmo que pudesse. E, ocasionalmente, o buffer não era suficiente.
O que eu implementei a seguir foi semelhante ao que você possui - escrevi um trabalho no servidor de teste que foi iniciado logo após o backup agendado e continuei pesquisando para ver quando o trabalho foi concluído. Mais tarde, isso foi alterado para ter apenas uma segunda etapa na tarefa de backup que atualizou uma tabela no servidor de teste. Na verdade, não é muito diferente, exceto que a tarefa de restauração só precisava observar uma tabela localmente, em vez de monitorar o histórico da tarefa remotamente. Pensando bem, isso poderia ter sido um gatilho nessa tabela chamada,
sp_start_job
para que o trabalho não tivesse que ser executado a cada n minutos (ou ser programado).A solução final foi encadear tarefas juntas ... quando o backup no servidor A termina, o Event Manager inicia a tarefa de restauração no servidor B. E se houvesse uma terceira e quarta tarefas, ou lógica condicional com base no que fazer quando um trabalho falha ou é bem-sucedido, etc., tudo isso pode ser considerado. O designer do fluxo de trabalho lembrará bastante o SSIS:
A mecânica subjacente do que estou descrevendo não é cirurgia com foguete, é claro. Você mesmo poderia escrever esse tipo de invólucro de encadeamento se sentasse e fizesse isso. Apenas fornecendo uma alternativa onde você não precisa.
fonte
O principal problema com a sua abordagem é que você precisa dar voltas contínuas até que algo aconteça (o que pode levar muito tempo ou até nunca) e isso não parece certo. É por isso que acho que você está fazendo a pergunta.
Então, que tal usar uma abordagem orientada a dados para o seu problema? Por exemplo, crie uma tabela 'audit' na qual cada trabalho grave quando ele inicia e termina:
Crie uma tabela de 'processamento' que lista todos os trabalhos e a ordem em que eles precisam ser executados:
Crie um gatilho de inserção na tabela de auditoria, para que, quando um trabalho for concluído e o registro de auditoria for inserido, o gatilho consulte a tabela de processamento para o próximo trabalho (por Ordem de Execução) e a inicie.
Os benefícios dessa abordagem são:
HTH
fonte