Como verificar se existe uma coluna em uma tabela do SQL Server?

1853

Preciso adicionar uma coluna específica se ela não existir. Eu tenho algo como o seguinte, mas sempre retorna false:

IF EXISTS(SELECT *
          FROM   INFORMATION_SCHEMA.COLUMNS
          WHERE  TABLE_NAME = 'myTableName'
                 AND COLUMN_NAME = 'myColumnName') 

Como posso verificar se existe uma coluna em uma tabela do banco de dados do SQL Server?

Maciej
fonte
12
Na verdade, não acho que haja algo errado com o código na pergunta: Funciona muito bem para mim no 2008 R2. (Talvez você o esteja executando no banco de dados errado? Talvez seu banco de dados fizesse distinção entre maiúsculas e minúsculas e você não tivesse o caso correto em suas seqüências myTableName / myColumnName? Esse tipo de consulta parece mais flexível que a solução COL_LENGTH: para executá-lo contra um banco de dados diferente e até mesmo através de um link de banco de dados prefixando adequadamente "INFORMATION_SCHEMA" não foi possível ver como fazer isso com a função de metadados COL_LENGTH..
mwardm
3
@mwardm - COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')funciona bem.
Martin Smith
6
Pequena dica relacionada: se você deseja atualizar uma coluna logo após a adição da coluna (acredito que muitos usuários estavam pesquisando este artigo para esse fim), você pode usar EXEC sp_executesqlcom a UPDATEdeclaração formada .
cassandrad
A verdadeira resposta é que você deve adicionar o banco de dados você está verificando contra por isso éFROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
Alex Kwitny

Respostas:

2054

SQL Server 2005 em diante:

IF EXISTS(SELECT 1 FROM sys.columns 
          WHERE Name = N'columnName'
          AND Object_ID = Object_ID(N'schemaName.tableName'))
BEGIN
    -- Column Exists
END

A versão de Martin Smith é mais curta:

IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
    -- Column Exists
END
Mitch Wheat
fonte
Na versão de Martin Smith, uma coisa a mencionar é não incluir columnName entre colchetes []. Quando columnName está dentro de colchetes [], ele vai dar nulo mesmo se a coluna existe na tabela
Hemendra
@HemendraSinghChauhan - isso é porque eles não fazem parte do nome. Você também descobrirá que, ao comparar com o nome emsys.columns
Martin Smith,
O @MartinSmith não sabia disso, eu estava usando sua resposta e me deparei com isso. Geralmente eu uso colchetes durante a adição de colunas, então usei-os também na função COL_LENGTH. Meu código era o seguinte:Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
Hemendra
Sim, isso não é válido. Os argumentos COL_LENGTHprecisam ser sem aspas. Teoricamente, é possível alguém criar uma coluna que realmente tenha um nome de [COLUMN_NAME]- por exemplo, CREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #Te seria ambíguo se essa não fosse a regra.
Martin Smith
987

Uma versão mais concisa

IF COL_LENGTH('table_name','column_name') IS NULL
BEGIN
/* Column does not exist or caller does not have permission to view the object */
END

O ponto sobre as permissões na exibição de metadados se aplica a todas as respostas, não apenas a esta.

Observe que o primeiro nome da tabela de parâmetros COL_LENGTHpode estar no formato de nome de uma, duas ou três partes, conforme necessário.

Um exemplo de referência a uma tabela em um banco de dados diferente é

COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate')

Uma diferença com esta resposta em comparação ao uso das visualizações de metadados é que as funções de metadados, como COL_LENGTHsempre, retornam apenas dados sobre alterações confirmadas, independentemente do nível de isolamento em vigor.

Martin Smith
fonte
11
Isso é menos legível do que algumas das outras respostas, provavelmente porque não é tão bem avaliado.
Bill Yang
38
@ Bill - menos legível de que maneira? Parece bem no Firefox. Esta resposta foi publicada mais de 2 anos depois da aceita, o que explica a classificação IMO. Se você quis dizer menos claro que existe, verifique se esse tipo de idioma é bastante comum no SQL Server. por exemplo, usando IF OBJECT_ID('TableName','U') IS NULLpara verificar a existência do objeto ou DB_ID('foo')para verificar a existência do banco de dados.
Martin Smith
59
@ MartinSmith Tenho certeza de que ele quis dizer menos legível, porque se você não conhecesse esse idioma e herdasse esse código de outra pessoa, não entenderia imediatamente o que o código faz. É como escrever em x>>2vez de x/4em C ++. O código mais detalhado ( if exists (select column_name from information_schema ...)) ocupa muito mais espaço, mas ninguém jamais arranhava a cabeça tentando descobrir o que faz.
21413 Kip
22
Além de mais conciso, esta é uma solução muito mais rápida. Acessando INFORMATION_SCHEMAvisualizações ou acessando o sys.columnsdisco, enquanto COL_LENGTHusa metadados do banco de dados em cache.
Wqw 13/01
7
Essa provavelmente não é a resposta mais bem classificada porque foi dada 2,5 anos depois da outra. É por isso que sempre verifico as datas ao comparar as classificações em duas respostas. Demora muito mais tempo para superar uma resposta que foi dada muito antes. ;)
Sean
149

Ajuste o abaixo para atender às suas necessidades específicas:

if not exists (select
                     column_name
               from
                     INFORMATION_SCHEMA.columns
               where
                     table_name = 'MyTable'
                     and column_name = 'MyColumn')
    alter table MyTable add MyColumn int

Editar para lidar com a edição da pergunta : Isso deve funcionar - observe cuidadosamente seu código para erros estúpidos; você está consultando INFORMATION_SCHEMA no mesmo banco de dados ao qual sua inserção está sendo aplicada, por exemplo? Você tem um erro de digitação no nome da tabela / coluna em qualquer uma das instruções?

Luke Bennett
fonte
3
Acabei de descobrir que a adição de TABLE_SCHEMA = 'mySchema' após a cláusula where corrige o problema.
Maciej
12
-1: não responde à pergunta do OP, apenas adiciona novas informações sobre como adicionar uma nova coluna, apesar de o OP não perguntar sobre isso, não aborda o comentário do OP.
ANeves 2/11/11
1
O +1 responde perfeitamente à pergunta do OP com um bônus das informações adicionais que o OP estava procurando no próximo. E era isso que eu estava procurando.
Bitterblue 11/11/19
74

Tente isso ...

IF NOT EXISTS(
  SELECT TOP 1 1
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE 
    [TABLE_NAME] = 'Employees'
    AND [COLUMN_NAME] = 'EmployeeID')
BEGIN
  ALTER TABLE [Employees]
    ADD [EmployeeID] INT NULL
END
Leon Tayson
fonte
6
Esse método também funciona com o SQL CE, enquanto alguns dos outros métodos mencionados não.
SWalters - Restabelece Monica
9
Você pode usar em SELECT 1vez de SELECT TOP 1 1;).
shA.t
4
Dentro de uma EXISTSinstrução, o SQL otimiza automaticamente as colunas (muito parecidas count(*)), assim SELECT *será suficiente.
Marc L.
Por uma questão de integridade, considere adicionar and [TABLE_SCHEMA] = '???'à cláusula WHERE.
Andrew Jens
51

Para as pessoas que estão verificando a existência da coluna, solte-a.

No SQL Server 2016, você pode usar novas instruções DIE em vez de grandes IFinvólucros

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
P ரதீப்
fonte
47

Eu preferiria INFORMATION_SCHEMA.COLUMNSuma tabela do sistema porque a Microsoft não garante a preservação das tabelas do sistema entre as versões. Por exemplo, dbo.syscolumnsainda funciona no SQL 2008, mas está obsoleto e pode ser removido a qualquer momento no futuro.

Christian Hayter
fonte
5
Bem, sim, isso é desnecessário, pois as INFORMATION_SCHEMAvisualizações contêm apenas metadados padrão ANSI. No entanto, isso é suficiente para um teste de existência.
Christian Hayter
3
A Microsoft diz "Em versões futuras do SQL Server, a Microsoft pode aumentar a definição de qualquer exibição do catálogo do sistema adicionando colunas ao final da lista de colunas. Recomendamos não usar a sintaxe SELECT * FROM sys.catalog_view_name no código de produção, pois o número de as colunas retornadas podem mudar e interromper seu aplicativo ". Isso implica que eles não removerão colunas ou alterarão sua ordem. Isso é boa compatibilidade com versões anteriores para todos os casos, exceto os periféricos.
siride
42

Você pode usar as visualizações do sistema de esquema de informações para descobrir praticamente tudo sobre as tabelas em que está interessado:

SELECT *
  FROM INFORMATION_SCHEMA.COLUMNS
 WHERE TABLE_NAME = 'yourTableName'
 ORDER BY ORDINAL_POSITION

Você também pode interrogar visualizações, procedimentos armazenados e praticamente qualquer coisa sobre o banco de dados usando as visualizações Information_schema.

anônimo
fonte
É exatamente isso que o questionário está usando, ele precisava saber como adicionar a coluna se ela não existisse.
Birel 12/03
35

Tente algo como:

CREATE FUNCTION ColumnExists(@TableName varchar(100), @ColumnName varchar(100))
RETURNS varchar(1) AS
BEGIN
DECLARE @Result varchar(1);
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = @TableName AND COLUMN_NAME = @ColumnName)
BEGIN
    SET @Result = 'T'
END
ELSE
BEGIN
    SET @Result = 'F'
END
RETURN @Result;
END
GO

GRANT EXECUTE ON  [ColumnExists] TO [whoever]
GO

Em seguida, use-o assim:

IF ColumnExists('xxx', 'yyyy') = 'F'
BEGIN
  ALTER TABLE xxx
  ADD yyyyy varChar(10) NOT NULL
END
GO

Ele deve funcionar no SQL Server 2000 e no SQL Server 2005. Não tem certeza sobre o SQL Server 2008, mas não vê por que não.

Matt Lacey
fonte
34

Primeiro verifique se a combinação table/ column( id/ name) existe em dbo.syscolumns(uma tabela interna do SQL Server que contém definições de campo) e, se não, emita a ALTER TABLEconsulta apropriada para adicioná-la. Por exemplo:

IF NOT EXISTS ( SELECT  *
            FROM    syscolumns
            WHERE   id = OBJECT_ID('Client')
                    AND name = 'Name' ) 
ALTER TABLE Client
ADD Name VARCHAR(64) NULL
mdb
fonte
28

Um bom amigo e colega me mostrou como você também pode usar um IFbloco com funções SQL OBJECT_IDe COLUMNPROPERTYno SQL SERVER 2005+ para verificar uma coluna. Você pode usar algo semelhante ao seguinte:

Você pode ver por si mesmo aqui

IF (OBJECT_ID(N'[dbo].[myTable]') IS NOT NULL AND
    COLUMNPROPERTY( OBJECT_ID(N'[dbo].[myTable]'), 'ThisColumnDoesNotExist', 'ColumnId') IS NULL)
BEGIN
    SELECT 'Column does not exist -- You can add TSQL to add the column here'
END
brazilianldsjaguar
fonte
1
E, claro, se você tiver certeza de que a tabela existe, poderá deixar de fora a primeira parte da condição e verificar COLUMNPROPERTYapenas.
Ruud Helderman
26
declare @myColumn   as nvarchar(128)
set @myColumn = 'myColumn'
if not exists (
    select  1
    from    information_schema.columns columns 
    where   columns.table_catalog   = 'myDatabase'
        and columns.table_schema    = 'mySchema' 
        and columns.table_name      = 'myTable' 
        and columns.column_name     = @myColumn
    )
begin
    exec('alter table myDatabase.mySchema.myTable add'
    +'    ['+@myColumn+'] bigint       null')
end
Tuomo Kämäräinen
fonte
22

Isso funcionou para mim no SQL 2000:

IF EXISTS 
(
    SELECT * 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'table_name' 
    AND column_name = 'column_name'
)
BEGIN
...
END
Joe M
fonte
21

Tente isto

SELECT COLUMNS.*
FROM   INFORMATION_SCHEMA.COLUMNS COLUMNS,
       INFORMATION_SCHEMA.TABLES TABLES
WHERE  COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
       AND Upper(COLUMNS.COLUMN_NAME) = Upper('column_name') 
Douglas Tondo
fonte
Você não precisa INFORMATION_SCHEMA.TABLESe não filtra colunas para uma tabela específica; portanto, às vezes, retorna mais de uma linha para os mesmos nomes de coluna em tabelas separadas;).
shA.t 15/06/2015
19

Eu precisava de algo semelhante para o SQL SERVER 2000 e, como o @Mitch aponta, isso só funciona em 2005+.

Deveria ajudar mais alguém, foi o que funcionou para mim no final:

if exists (
    select * 
    from 
        sysobjects, syscolumns 
    where 
        sysobjects.id = syscolumns.id 
        and sysobjects.name = 'table' 
        and syscolumns.name = 'column')
FrostbiteXIII
fonte
15
if exists (
  select * 
  from INFORMATION_SCHEMA.COLUMNS 
  where TABLE_NAME = '<table_name>' 
  and COLUMN_NAME = '<column_name>'
) begin
  print 'Column you have specified exists'
end else begin
  print 'Column does not exist'
end
BYRAKUR SURESH BABU
fonte
13
IF NOT EXISTS( SELECT NULL
            FROM INFORMATION_SCHEMA.COLUMNS
           WHERE table_name = 'TableName'
             AND table_schema = 'SchemaName'
             AND column_name = 'ColumnName')  BEGIN

  ALTER TABLE [SchemaName].[TableName] ADD [ColumnName] int(1) NOT NULL default '0';

END;
Na30m
fonte
2
Eu acho que você quis dizer table_schema = 'schema_name'.
Tab Alleman
11

Uma versão de tabela temporária da resposta aceita :

if (exists(select 1 
             from tempdb.sys.columns  
            where Name = 'columnName'
              and Object_ID = object_id('tempdb..#tableName')))
begin
...
end
crokusek
fonte
1
Como isso é diferente da resposta aceita? Uma tabela temporária não funcionaria na resposta aceita?
John Saunders
1
Corrigir. A resposta aceita não funciona para tabelas temporárias porque 'sys.columns' deve ser especificado como 'tempdb.sys.columns' e o nome da tabela deve ser precedido por 'tempdb ..'.
crokusek
10
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so  
where sc.name like '%col_name%' and so.type='U'
Nishad
fonte
8

A resposta do trigo é boa, mas assume que você não possui pares de nome de tabela / nome de coluna idênticos em qualquer esquema ou banco de dados. Para torná-lo seguro para essa condição, use este ...

select *
from Information_Schema.Columns
where Table_Catalog = 'DatabaseName'
  and Table_Schema = 'SchemaName'
  and Table_Name = 'TableName'
  and Column_Name = 'ColumnName'
Daniel Barbalace
fonte
8

Existem várias maneiras de verificar a existência de uma coluna. Eu recomendo fortemente usar INFORMATION_SCHEMA.COLUMNScomo ele é criado para se comunicar com o usuário. Considere as seguintes tabelas:

 sys.objects
 sys.columns

e até alguns outros métodos de acesso disponíveis para verificar system catalog.

Além disso, não há necessidade de usar SELECT *, basta testá-loNULL value

IF EXISTS(
           SELECT NULL 
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE
             TABLE_NAME = 'myTableName'
             AND COLUMN_NAME = 'myColumnName'
         ) 
Ali Elmi
fonte
1
Não importa mesmo se você SELECT *com EXISTS, porque quando existe é usado ele realmente não selecione todas as linhas e todas as colunas, internamente ele apenas verifica a existência e na verdade não verifica a existência de todas as linhas e colunas
Pawan Nogariya
7

Uma das soluções mais simples e compreensíveis é:

IF COL_LENGTH('Table_Name','Column_Name') IS NULL
 BEGIN
    -- Column Not Exists, implement your logic
 END 
ELSE
 BEGIN
    -- Column Exists, implement your logic
 END
Arsman Ahmad
fonte
7

Aqui está um script simples que eu uso para gerenciar a adição de colunas no banco de dados:

IF NOT EXISTS (
        SELECT *
        FROM sys.Columns
        WHERE Name = N'QbId'
            AND Object_Id = Object_Id(N'Driver')
        )
BEGIN
    ALTER TABLE Driver ADD QbId NVARCHAR(20) NULL
END
ELSE
BEGIN
    PRINT 'QbId is already added on Driver'
END

Neste exemplo, o Nameé o ColumnNamea ser adicionado e Object_Idé oTableName

UJS
fonte
4

A consulta abaixo pode ser usada para verificar se a coluna pesquisada existe ou não na tabela. Podemos tomar uma decisão com base no resultado pesquisado também como mostrado abaixo.

IF EXISTS (SELECT 'Y' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = <YourTableName> AND COLUMN_NAME = <YourColumnName>)
  BEGIN
    SELECT 'Column Already Exists.'
  END
  ELSE
  BEGIN
    ALTER TABLE <YourTableName> ADD <YourColumnName> <DataType>[Size]
  END
Suraj Kumar
fonte
3

Ainda outra variação ...

SELECT 
  Count(*) AS existFlag 
FROM 
  sys.columns 
WHERE 
  [name] = N 'ColumnName' 
  AND [object_id] = OBJECT_ID(N 'TableName')
Manuel Alves
fonte
1

tabela -> tabela de scripts como -> novas janelas - você possui um script de design. verifique e encontre o nome da coluna em novas janelas

arnav
fonte
1

Execute a consulta abaixo para verificar se a coluna existe na tabela fornecida:

IF(SELECT COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName') IS NOT NULL
PRINT 'Column Exists in the given table';
S Krishna
fonte
1

Outra contribuição é o exemplo a seguir que adiciona a coluna, se não existir.

    USE [Northwind]
    GO

    IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
                    WHERE TABLE_NAME = 'Categories'
                        AND COLUMN_NAME = 'Note')
    BEGIN

    ALTER TABLE Categories ADD Note NVARCHAR(800) NULL

    END
    GO

Espero que ajude. Simone

Simone Spagna
fonte
0
IF EXISTS(SELECT 1 FROM sys.columns 
      WHERE Name = N'columnName'
      AND Object_ID = Object_ID(N'schemaName.tableName'))

Essa deve ser a maneira mais fácil e a solução direta para esse problema. Eu usei isso várias vezes para cenários semelhantes. Funciona como um encanto, sem dúvidas.

Ilangeeran
fonte
0
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_CATALOG = 'Database Name'
and TABLE_SCHEMA = 'Schema Name'
and TABLE_NAME = 'Table Name'
and COLUMN_NAME = 'Column Name'
and DATA_TYPE = 'Column Type') -- Where statement lines can be deleted.

BEGIN
--COLUMN EXISTS IN TABLE
END

ELSE BEGIN
--COLUMN DOES NOT EXISTS IN TABLE
END
Mohamad Reza Shahrestani
fonte
0

Faça algo se a coluna não existir:

BEGIN
    IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
    BEGIN
        //Do something
    END
END;

Faça algo se a coluna existir:

BEGIN
    IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
    BEGIN
        //Do something
    END
END;
Jagjit Singh
fonte