Adicione uma coluna a uma tabela, se ela ainda não existir

188

Quero escrever uma consulta para o MS SQL Server que adicione uma coluna em uma tabela. Mas não quero exibir nenhum erro quando executo / executo a seguinte consulta.

Estou usando esse tipo de consulta para adicionar uma tabela ...

IF EXISTS (
       SELECT *
       FROM   sys.objects
       WHERE  OBJECT_ID = OBJECT_ID(N'[dbo].[Person]')
              AND TYPE IN (N'U')
   )

Mas não sei como escrever esta consulta para uma coluna.

Tavousi
fonte
1
possível duplicata Como verificar se a coluna existe na tabela SQL Server
Martin Smith
Você deve usar sys.tablesem vez do "genérico" sys.objects- então você não tem que especificar o tipo explicitamente (é óbvio a partir do sys.tablesjá ....)
marc_s
COL_LENGTH A alternativa funciona apenas no SQL-Server 2008, mas funciona.
Paul-Henri

Respostas:

219

Você pode usar uma construção semelhante usando a sys.columnstabela io sys.objects.

IF NOT EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].[Person]') 
         AND name = 'ColumnName'
)
Lieven Keersmaekers
fonte
42
Observe que, neste caso, você deseja usar SE NÃO EXISTE no seu código real.
Nac
2
Para otimizado consulta que você pode usar top 1 com select
Banketeshvar Narayan
11
@BanketeshvarNarayan isso está incorreto. Os planos de execução para subconsultas em uma EXISTScláusula são idênticos. Coisas como SELECT 1ou SELECT TOP 1são desnecessárias. A EXISTSprópria cláusula informa ao otimizador de consulta para executar apenas as leituras mínimas necessárias para avaliar o EXISTS... pelo menos no SQL Server. Outros mecanismos de banco de dados podem ter um otimizador de consulta mais ou menos eficiente.
21915 Kenneth Cochran
9
@BanketeshvarNarayan Se você está otimizando suas ADD Columnconsultas ... deve executá-las com muita frequência!
Fenton
1
@ user391339 - Publiquei uma construção semelhante à do OP, mas sim, se você quiser executar uma ação se a coluna não existir, a instrução será SE NÃO EXISTIR. Eu realmente não sinto a necessidade de editar a resposta para isso, mas sinta-se à vontade para editar a si mesmo se você acha que isso é uma melhoria.
Lieven Keersmaekers
91
IF COL_LENGTH('table_name', 'column_name') IS NULL
BEGIN
    ALTER TABLE table_name
    ADD [column_name] INT
END
SPL
fonte
1
Eu tentei fazer isso, mas ele retorna um erro que afirma que a função COL_LENGTH não existe.
ThEpRoGrAmMiNgNoOb
3
Requer SQL Server 2008
Robert Brown
6
Pequena adição - não se deve usar colchetes no nome da coluna, pois COL_LENGTH('table_name', '[column_name]')sempre retorna nulo no SQL Server 2016 ( COL_LENGTH('[table_name]', 'column_name') works as expected).
stop-cran
33

Outra alternativa. Eu prefiro essa abordagem porque é menos escrita, mas as duas realizam a mesma coisa.

IF COLUMNPROPERTY(OBJECT_ID('dbo.Person'), 'ColumnName', 'ColumnId') IS NULL
BEGIN
    ALTER TABLE Person 
    ADD ColumnName VARCHAR(MAX) NOT NULL
END

Notei também que o seu está procurando onde existe uma tabela que obviamente é exatamente essa

 if COLUMNPROPERTY( OBJECT_ID('dbo.Person'),'ColumnName','ColumnId') is not null
JStead
fonte
2
Eu gosto disso. Acho que a melhor parte de postar aqui é encontrar joias como essa.
precisa saber é o seguinte
2
O que é 'ColumnId'?
Marius Stănescu
'ColumnId' é o nome da propriedade da coluna na qual você está verificando. Você provavelmente poderia ter usado qualquer nome de propriedade que exista em uma coluna, como nome etc.
Jacques Bosch
5

Aqui está outra variação que funcionou para mim.

IF NOT EXISTS (SELECT 1
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE upper(TABLE_NAME) = 'TABLENAME'
        AND upper(COLUMN_NAME) = 'COLUMNNAME')
BEGIN
    ALTER TABLE [dbo].[Person] ADD Column
END
GO

EDIT: observe que as INFORMATION_SCHEMAvisualizações nem sempre podem ser atualizadas, use SYS.COLUMNS:

IF NOT EXISTS (SELECT 1 FROM SYS.COLUMNS....

Adil H. Raza
fonte
0
IF NOT EXISTS (SELECT * FROM syscolumns
  WHERE ID=OBJECT_ID('[db].[Employee]') AND NAME='EmpName')
  ALTER TABLE [db].[Employee]
  ADD [EmpName] VARCHAR(10)
GO

Espero que isso ajude. Mais informações

ShaileshDev
fonte
Isso funcionou para mim no SqlServer 2000, enquanto a resposta aceita não. As visualizações sys. * Parecem ter sido adicionadas ao redor do SqlServer 2005, cf. docs.microsoft.com/en-us/sql/relational-databases/…
ZeRemz
0

Ao procurar uma coluna em outro banco de dados, você pode simplesmente incluir o nome do banco de dados:

IF NOT EXISTS (
  SELECT * 
  FROM   DatabaseName.sys.columns 
  WHERE  object_id = OBJECT_ID(N'[DatabaseName].[dbo].[TableName]') 
         AND name = 'ColumnName'
)
Esdras
fonte
-1
IF NOT EXISTS (SELECT 1  FROM SYS.COLUMNS WHERE  
OBJECT_ID = OBJECT_ID(N'[dbo].[Person]') AND name = 'DateOfBirth')
BEGIN
ALTER TABLE [dbo].[Person] ADD DateOfBirth DATETIME
END
Code First
fonte