Eu tenho uma tabela de teste simples como esta:
CREATE TABLE MyTable (x INT);
Dentro de uma transação, tento adicionar uma coluna e inserir na coluna recém-criada:
BEGIN TRANSACTION;
PRINT 'Adding column, ''SupplementalDividends'', to MyTable table.';
ALTER TABLE MyTable
ADD SupplementalDividends DECIMAL(18,6);
PRINT 'Column added successfully....';
PRINT 'Ready to INSERT into MyTable ...';
INSERT INTO MyTable (x, SupplementalDividends)
VALUES (1, 3.2);
PRINT '**** CHANGES COMPLETE -- COMMITTING.';
COMMIT TRANSACTION;
O problema é uma mensagem de erro quando executo o código acima:
Invalid column name 'SupplementalDividends'.
Por que isso está causando um erro? Se eu adicionar a coluna em um lote diferente, fora da transação, ela funcionará. Meu problema é que eu quero adicionar a coluna dentro da transação. Por que o erro?
sql-server
sql-server-2008-r2
t-sql
Tom Baxter
fonte
fonte
schema.ObjectName
. Um bom começo para se adaptar boas práticas :-)Respostas:
Só quero esclarecer que esse é um problema no tempo de execução, não no tempo de compilação e não tem nada a ver com o fato de que eles estão na mesma transação . Por exemplo, vamos assumir que temos esta tabela:
O lote a seguir analisa com êxito (tempo de compilação), mas em tempo de execução, ele recebe o erro mencionado na pergunta:
Em um editor de consultas no Management Studio, você pode contornar isso facilmente, por:
Colocando um separador de lote entre eles, assim:
Se você estiver executando isso fora do SQL Server (por exemplo, enviando um lote SQL a partir do código do aplicativo), basta enviar os dois lotes separadamente de maneira semelhante ou, se for absolutamente necessário enviá-lo como um único lote, poderá use SQL dinâmico (como na resposta de Gianluca ) para adiar a resolução de nomes.
fonte
É uma questão vinculativa. O código é vinculado aos metadados da tabela no tempo de compilação e não é vinculado tardiamente. Tente usar EXEC e SQL dinâmico para superar essa limitação:
Outra opção é usar um procedimento armazenado para inserir os dados: a ligação tardia se aplica ao procedimento armazenado, mas não a consultas ad-hoc. Novamente, você precisaria usar o SQL dinâmico para criar o procedimento, mas isso poderia facilitar a passagem de parâmetros:
Um procedimento armazenado temporário também funcionaria:
fonte
Estou curioso para saber por que você está alterando uma tabela e inserindo um valor nessa coluna dentro da mesma transação.
Quase não há chance de que você precise alterar a tabela (da mesma maneira exata) novamente, a menos que seja revertida a cada hora / dia, por que fazê-lo em uma transação?
Seu alter ainda não foi confirmado e, portanto, não é encontrado quando você tenta inseri-lo.
Meu conselho é separar suas tarefas DDL e DML (pelo menos em transações separadas de qualquer maneira).
fonte