Ao criar um procedimento armazenado no SQL Server, você pode se referir a tabelas que não existem. Mas, se a tabela existir, qualquer coluna à qual você fizer referência no procedimento deverá existir nessa tabela ( Resolução de Nome Adiada ).
É possível instruir o SQL Server a adiar a resolução de nomes de todas as tabelas referenciadas em um procedimento, independentemente de existirem ou não? Eu quero manter a verificação geral da sintaxe, portanto, mesmo que fosse possível, hackear a definição do procedimento armazenado em uma tabela do sistema não é uma opção.
Espero que minha solicitação para fazer isso possa parecer um pouco estranha , então aqui está um histórico: Eu gero automaticamente definições de tabela e procedimentos armazenados de um aplicativo escrito em C# e é muito difícil para mim alterar o código para ordenar as alterações conforme as necessidades do SQL eles. Meu código "garante" que o esquema é consistente em uma transação, mas atualmente não posso garantir que as colunas da tabela sejam definidas antes de eu definir o procedimento armazenado que as referencia.
Abaixo está um exemplo canônico do SQL criado pelo C# que "ilustra" o problema que estou tentando resolver.
--Say this table already exists.
CREATE TABLE myTable
(
a NVARCHAR(MAX)
)
GO
--My C# code creates something like this
BEGIN TRAN
GO
--the stored procedure gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
SELECT a,b FROM myTable
END
--then the table update
ALTER TABLE myTable
ADD b nvarchar(MAX)
COMMIT TRAN
É possível corrigir isso no código C #, mas espero um simples ajuste "mágico" que possa fazer no SQL. Isso vai economizar muito tempo para mim.
Não.
Eu me sinto muito culpado apenas digitando isso, mas não, infelizmente. É a primeira vez que ouço falar desse caso de uso e faz todo o sentido. É melhor enviar uma solicitação em https://feedback.azure.com/forums/908035-sql-server e seus netos poderão fazê-lo. ;-)
Apenas no caso de você ainda estar interessado, há uma possível solução alternativa que você pode empregar. Aqui está o código atualizado, que introduz a
#deferResolution
tabela temporária para cada consulta no procedimento. Como a tabela temporária só existirá em tempo de execução, o procedimento é capaz de compilar mesmo que as colunas apropriadas ainda não existam emmyTable
.Você ainda obterá o mesmo plano de execução (sem referência à
#deferResolution
tabela) para cada instrução no procedimento devido à maneira como o otimizador de consulta pode provar que issoWHERE NOT EXISTS
sempre é avaliado como verdadeiro.Dito isso, este é um hack terrível apresentado principalmente por interesse intelectual e pode haver um caso extremo em que ele falha. Como Aaron menciona, provavelmente seria melhor fazer todas as alterações de esquema na ordem correta.