Desativando a verificação do esquema na criação de funções / procedimentos armazenados

17

Estou tentando automatizar o processo que executa alterações no banco de dados do SQL Server 2008 R2. O processo que eu coloco em prática descarta e recria meus procedimentos e funções armazenados, além de executar scripts para alterar as tabelas / colunas / dados. Infelizmente, um dos scripts requer que uma das funções seja implementada primeiro. Mas não consigo executar todas as alterações de proc / função armazenadas primeiro, porque ele depende da adição de colunas dos scripts de alteração de tabelas / colunas / dados.

Eu queria saber se era possível executar procedimentos e funções armazenados sem o SQL Server validar as colunas usadas na definição da função / SP? Tentei procurar, mas não consegui encontrar uma condição ou comando para ativar isso.

Brian Mains
fonte
Parece que você pode apenas precisar reorganizar a criação do objeto em seus scripts.
22412 Thomas Stringer
@shark É que um script de mudança requer uma dependência de uma função, o que não estava na época ... para fazer isso exigiria intervenção manual; Eu queria algo mais automático.
Brian Mains

Respostas:

20

Você pode criar procedimentos armazenados que fazem referência a objetos que ainda não existem (por exemplo, tabelas e funções). Você não pode criar procedimentos armazenados que fazem referência a colunas que ainda não existem em objetos que já existem. Essa é a faca de dois gumes da resolução de nomes adiados - o SQL Server oferece o benefício da dúvida em alguns casos, mas não em todos. Veja as idéias de Erland SET STRICT_CHECKS ON;para obter algumas idéias dos locais em que isso funciona e dos locais em que está quebrado:

http://www.sommarskog.se/strict_checks.html

(E como ele gostaria do oposto do que você procura - você deseja permitir que qualquer coisa seja compilada, independentemente da existência, e ele deseja que todas as colunas ou tabelas sejam verificadas.)

Não existe uma configuração como SET DEFERRED_NAME_RESOLUTION OFF;se tivesse sido solicitada:

http://connect.microsoft.com/sql/127152

E não há configuração como IGNORE ALL_RESOLUTION;.


Você pode contornar isso de várias maneiras, incluindo:

(a) use SQL dinâmico nos procedimentos armazenados afetados.

(b) construa um stub para CREATE PROCEDUREnada, depois execute o restante do seu script e execute um ALTER PROCEDUREque tenha o corpo real (em essência, implante o procedimento em duas fases).

(c) torne sua ferramenta de implantação mais inteligente sobre a ordem das operações. Se as alterações na tabela exigirem a presença de uma função, faça o script dessas alterações por último. Ferramentas de comparação de esquema como o SQL Compare do RedGate são muito boas para gerar scripts para você na ordem de dependência adequada. Você não menciona qual ferramenta está usando, mas se não estiver fazendo isso ...

(d) Martin Smith tem uma solução interessante aqui , mas eu não brinquei com isso.

Aaron Bertrand
fonte
Uau, esse hack de Martin Smith é brilhantemente inteligente. Eu me sentiria sujo ao usá-lo agora, mas com 20 e poucos anos teria.
John Zabroski 18/04/19
1

Você pode criar um procedimento armazenado que exclui ou renomeia o objeto em questão primeiro e depois executa o procedimento armazenado original como SQL dinâmico. Dessa forma, você não precisa reescrever o procedimento armazenado real para usar o SQL dinâmico.

O código abaixo executa um procedimento armazenado que referencia colunas que ainda não existem (Expense_Super_Compare)

IF OBJECT_ID('Expense_Super_Compare_Results', 'U') IS NOT NULL
BEGIN
     EXEC('DROP TABLE Expense_Super_Compare_Results');
END

exec('exec dbo.Expense_Super_Compare');
Lou Fancy
fonte