Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Recompilar procs armazenados?


Entendo sua pergunta como 'quando faço uma alteração de esquema, quero validar todos os procedimentos que ainda executam corretamente com o novo esquema'. Ou seja. se você descartar uma coluna que é referenciada em um SELECT em um procedimento, você deseja que ela seja sinalizada, pois requer alterações. Então, especificamente, não entendo sua pergunta como 'quero que o procedimento recompile na próxima execução', pois esse trabalho é feito para você pelo mecanismo, que detectará a alteração de versão de metadados associada a qualquer alteração de esquema e descartará o existente planos de execução em cache.

Minha primeira observação é que o que você descreve em sua pergunta geralmente é o trabalho de um TESTE e você deve ter uma etapa de controle de qualidade em seu processo de implantação que valide a nova 'compilação'. A melhor solução que você pode ter é implementar um conjunto mínimo de testes de unidade que, no mínimo, itere todos os seus procedimentos armazenados e valide a execução de cada um para correção, em uma implantação de teste. Isso eliminaria praticamente todas as surpresas, pelo menos as eliminaria onde dói (na produção ou no local do cliente).

Sua próxima melhor opção é confiar em suas ferramentas de desenvolvimento para rastrear essas dependências. O Visual Studio Database 2008 Database Edition fornece essa funcionalidade pronta para uso e se encarrega de validar qualquer alteração feita no esquema.

E, finalmente, sua última opção é fazer algo semelhante ao que KM sugeriu:automatizar uma iteração através de todos os seus procedimentos dependendo do objeto modificado (e todos os procedimentos dependendo dos dependentes e assim por diante e assim por diante recursivamente). Não será suficiente marcar os procedimentos para recompilação, o que você realmente precisa é executar o ALTER PROCEDURE para acionar uma análise do seu texto e uma validação do esquema (as coisas são um pouco diferentes em T-SQL vs. sua linguagem usual ciclo de compilação/execução, a 'compilação' per se ocorre apenas quando o procedimento é realmente executado). Você pode começar iterando pelo sys.sql_dependencies para encontrar todas as dependências do seu objeto alterado e também encontrar a 'definição do módulo' das dependências de sys.sql_modules :
with cte_dep as (
   select object_id
      from sys.sql_dependencies
    where referenced_major_id = object_id('<your altered object name>') 
    union all
    select d.object_id
    from sys.sql_dependencies d
        join cte_dep r on d.referenced_major_id = r.object_id
    )
, cte_distinct as (
    select distinct object_id
        from cte_dep)
select object_name(c.object_id)
    , c.object_id 
    , m.definition
    from cte_distinct c
    join sys.sql_modules m on c.object_id = m.object_id

Você pode então percorrer os 'módulos' dependentes e recriá-los (ou seja, soltá-los e executar o código na 'definição'). Observe que um 'módulo' é mais genérico do que um procedimento armazenado e abrange também exibições, gatilhos, funções, regras, padrões e filtros de replicação. 'módulos' criptografados não terão definição a definição disponível e para estar absolutamente correto você também deve considerar as várias configurações capturadas em sys.sql_modules (ansi nulls, vinculação de esquema, executar as cláusulas etc).

Se você usar SQL ynamic, isso não poderá ser verificado. Ele não será capturado por sys.sql_dependencies , nem será validado 'recriando' o módulo.

No geral, acho que sua melhor opção, com grande margem, é implementar a validação de testes de unidade.