Esta é mais uma questão geral. Por que você não pode adicionar um índice filtrado no mesmo escopo da transação ao adicionar a nova coluna em primeiro lugar? A solução é obviamente simples, basta fazer duas transações onde você cancela manualmente as alterações feitas na primeira, caso ela retorne um erro.
Mesmo assim, estou interessado no raciocínio técnico por trás desse fenômeno, especialmente considerando que já fiz isso antes. Eu ativei alguma verificação superzelosa interessante no SSMS? Exemplo de código abaixo, e obrigado!
--CREATE TABLE TEST_TABLE (ID INT IDENTITY(1,1) PRIMARY KEY)
BEGIN TRY
BEGIN TRAN
IF NOT EXISTS (SELECT * FROM sys.columns WHERE name = 'NEWCOL_ID'
AND OBJECT_NAME(object_id) = 'TEST_TABLE')
BEGIN
ALTER TABLE TEST_TABLE
ADD NEWCOL_ID INT NULL
CREATE NONCLUSTERED INDEX NEWCOL_ID_IDX
ON TEST_TABLE (NEWCOL_ID ASC) WHERE NEWCOL_ID IS NOT NULL
END
COMMIT TRAN
END TRY
BEGIN CATCH
BEGIN
ROLLBACK TRANSACTION
PRINT(ERROR_MESSAGE())
END
END CATCH;
Você pode fazer isso dentro da mesma transação, só precisa ser empurrado para um escopo filho, compilado separadamente.
Você também pode fazer isso dentro do mesmo escopo e na mesma transação se a tabela ainda não existir.
Nesse segundo caso, a referência à coluna está sujeita à compilação adiada, pois a tabela ainda não existe quando o SQL Server compila o lote. Consulte Resolução e Compilação de Nomes Adiados em BOL