Temos um procedimento armazenado que os usuários podem executar manualmente para obter alguns números atualizados de um relatório usado constantemente ao longo do dia.
Eu tenho um segundo procedimento armazenado que deve ser executado após a execução do primeiro procedimento armazenado, pois é baseado nos números obtidos com esse primeiro procedimento armazenado, no entanto, leva mais tempo para ser executado e é para um processo separado, por isso não quero faça o usuário esperar enquanto este segundo procedimento armazenado é executado.
Existe uma maneira de um procedimento armazenado iniciar um segundo procedimento armazenado e retornar imediatamente sem aguardar resultados?
Estou usando o SQL Server 2005.
Respostas:
Parece que existem várias maneiras de fazer isso, mas achei que a maneira mais simples foi a sugestão de Martin de configurar o procedimento em um trabalho SQL e iniciá-lo usando o comando asynchronous sp_start_job do meu procedimento armazenado.
Isso só funciona para mim porque não preciso especificar nenhum parâmetro para o meu procedimento armazenado.
Outras sugestões que podem funcionar dependendo da sua situação são
Executar o processo de forma assíncrona no código responsável pela execução do procedimento armazenado, como sugerido pelo Sr.Brownstone .
Não é uma má idéia, no entanto, no meu caso, o procedimento armazenado é chamado de vários locais, portanto, encontrar todos esses locais e garantir que eles chamam o segundo procedimento também não parecia tão prático. Além disso, o segundo procedimento armazenado é bastante crítico, e esquecer de executá-lo pode causar alguns problemas importantes para a nossa empresa.
fonte
EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Também nem o Service Broker, nem o Sql Agent, existem no Azure. Não sei por que a Microsoft, depois de uma década e meia de pessoas perguntando, se recusa a adicionarEXECUTE ASYNC RematerializeExpensiveCacheTable
.Você poderia usar o service broker juntamente com a ativação na fila. Com isso, você pode postar os parâmetros para a chamada de procedimento na fila. Isso leva tanto tempo quanto uma inserção. Depois que a transação é confirmada e, potencialmente, mais alguns segundos, a ativação chama automaticamente o procedimento do receptor de forma assíncrona. É necessário apenas pegar os parâmetros da fila e fazer o trabalho desejado.
fonte
Esta pergunta antiga merece uma resposta mais abrangente. Alguns deles são mencionados em outras respostas / comentários aqui, outros podem ou não funcionar para a situação específica do OP, mas podem funcionar para outros que procuram chamar procs armazenados de forma assíncrona a partir do SQL.
Apenas para ser totalmente explícito: o TSQL não possui (por si só) a capacidade de iniciar outras operações do TSQL de forma assíncrona .
Isso não significa que você ainda não tem muitas opções:
sp_start_job
. Se você precisar monitorar o progresso deles programaticamente, verifique se os trabalhos atualizam uma tabela JOB_PROGRESS personalizada (ou verifique se eles terminaram de usar a função não documentada,xp_sqlagent_enum_jobs
conforme descrito neste excelente artigo de Gregory A. Larsen). Você deve criar quantos trabalhos separados desejar para que processos paralelos sejam executados, mesmo se eles estiverem executando o mesmo processo armazenado com parâmetros diferentes.sp_oacreate
esp_oamethod
para iniciar um novo processo chamando um ao outro proc armazenado, conforme descrito neste artigo , também por Gregory A. Larsen.Parallel_AddSql
eParallel_Execute
conforme descrito neste artigo por Alan Kaplan (somente SQL2005 +).Se fosse eu, provavelmente usaria vários trabalhos do SQL Agent em cenários mais simples e um pacote SSIS em cenários mais complexos.
No seu caso, chamar os trabalhos do SQL Agent parece uma opção simples e gerenciável.
Um comentário final : o SQL já tenta paralelizar operações individuais sempre que pode *. Isso significa que a execução de duas tarefas ao mesmo tempo, em vez de uma após a outra, não garante que elas terminem mais cedo. Teste com cuidado para ver se ele realmente melhora alguma coisa ou não.
Tivemos um desenvolvedor que criou um pacote DTS para executar 8 tarefas ao mesmo tempo. Infelizmente, era apenas um servidor com 4 CPUs :)
* Assumindo configurações padrão. Isso pode ser modificado alterando o Grau máximo de paralelismo ou Máscara de afinidade do servidor ou usando a dica de consulta MAXDOP.
fonte
Sim, um método:
fonte
sp_start_job
para iniciá-lo ou criar trabalhos conforme necessário dinamicamente para evitar pesquisas a cada minuto, mas a complexidade para esse caso provavelmente significa que não será mais simples que o service broker.sp_start_job
retorna imediatamente. Não consigo lembrar de que permissões ele precisa.Outra possibilidade seria fazer com que o primeiro procedimento armazenado grave em uma tabela de auditoria quando for concluído e coloque um gatilho na tabela de auditoria que inicia o segundo procedimento armazenado quando a tabela de auditoria é gravada. Não é necessário pesquisar continuamente e não é necessário um trabalho extra do SQL Server Agent.
fonte
INSERT
ouUPDATE
, não de forma assíncrona, portanto, Martin está certo de que o primeiro procedimento continuaria esperando até o retorno do segundo.