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?


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

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.


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?


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

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

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.



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.


É 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.


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

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

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

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

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') 

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')

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

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;

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

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'

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'

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'
         ) 

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

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


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

3

Ainda outra variação ...

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

1

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


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';

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


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.


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

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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.