¿Cómo verificar si existe una columna en una tabla de SQL Server?

Necesito agregar una columna específica si no existe. Tengo algo como lo siguiente, pero siempre devuelve falso:

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

¿Cómo puedo verificar si existe una columna en una tabla de la base de datos de SQL Server?

SQL Server 2005 en adelante:

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

La versión de Martin Smith es más corta:

 IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL BEGIN -- Column Exists END 

Una versión más 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 

El punto acerca de los permisos para ver los metadatos se aplica a todas las respuestas, no solo a esta.

Tenga en cuenta que el primer nombre de la tabla de parámetros para COL_LENGTH puede tener el formato de nombre de una, dos o tres partes según sea necesario.

Un ejemplo que hace referencia a una tabla en una base de datos diferente es

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

Una diferencia con esta respuesta en comparación con el uso de las vistas de metadatos es que las funciones de metadatos, como COL_LENGTH siempre devuelven datos sobre los cambios comprometidos independientemente del nivel de aislamiento vigente.

Ajusta el siguiente para adaptarlo a tus requisitos específicos:

 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 lidiar con la edición de la pregunta : Eso debería funcionar: mire detenidamente su código para detectar errores estúpidos; ¿Está consultando INFORMATION_SCHEMA en la misma base de datos a la que se está aplicando su inserción, por ejemplo? ¿Tiene un error tipográfico en el nombre de su tabla / columna en cualquier statement?

Prueba esto…

 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 

Preferiría INFORMATION_SCHEMA.COLUMNS en una tabla del sistema porque Microsoft no garantiza preservar las tablas del sistema entre las versiones. Por ejemplo, dbo.syscolumns todavía funciona en SQL 2008, pero está obsoleto y podría eliminarse en cualquier momento en el futuro.

Puede usar las vistas del sistema de esquema de información para descubrir casi cualquier cosa sobre las tablas que le interesan:

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

También puede interrogar vistas, procedimientos almacenados y casi cualquier cosa sobre la base de datos utilizando las vistas de Information_schema.

Primero compruebe si la combinación de table / column ( id / name ) existe en dbo.syscolumns (una tabla interna de SQL Server que contiene definiciones de campo) y, si no, emita la consulta ALTER TABLE apropiada para agregarla. Por ejemplo:

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

Pruebe 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 

Entonces úsalo así:

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

Debería funcionar en SQL Server 2000 y SQL Server 2005. No estoy seguro acerca de SQL Server 2008, pero no veo por qué no.

Para las personas que están verificando la existencia de la columna para soltarlo.

En SQL Server 2016 puede usar nuevas sentencias DIE en lugar de grandes contenedores IF

 ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name 
 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 

Un buen amigo y colega mío me mostró cómo también puede usar un bloque IF con las funciones SQL OBJECT_ID y COLUMNPROPERTY en SQL SERVER 2005+ para verificar una columna. Puede usar algo similar a lo siguiente:

Puedes verlo por ti mismo aquí

 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 

Esto funcionó para mí en SQL 2000:

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

Prueba esto

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

Necesitaba algo similar para SQL SERVER 2000 y, como señala @Mitch, esto solo funciona en 2005+.

Si ayuda a alguien más, esto es lo que funcionó para mí al final:

 if exists ( select * from sysobjects, syscolumns where sysobjects.id = syscolumns.id and sysobjects.name = 'table' and syscolumns.name = 'column') 
 if exists (select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='' and COLUMN_NAME='') begin print 'Column you have specified exists' end else begin print 'Column does not exists' end 
 IF NOT EXISTS( SELECT NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'tablename' AND table_schema = 'db_name' AND column_name = 'columnname') THEN ALTER TABLE `TableName` ADD `ColumnName` int(1) NOT NULL default '0'; END IF; 
 select distinct object_name(sc.id) from syscolumns sc,sysobjects so where sc.name like '%col_name%' and so.type='U' 

Una versión de tabla temporal de la respuesta aceptada :

 if (exists(select 1 from tempdb.sys.columns where Name = 'columnName' and Object_ID = object_id('tempdb..#tableName'))) begin ... end 

La respuesta de Wheat es buena, pero supone que no tiene ningún nombre de tabla / nombre de columna idénticos en ningún esquema o base de datos. Para que sea seguro para esa condición, usa esto …

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

Una de las soluciones más simples y comprensibles es:

 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 

Aquí hay un script simple que utilizo para administrar la adición de columnas en la base de datos:

 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 

En este ejemplo, el Name es el ColumnName de ColumnName que se agregará y Object_Id es el nombre de Object_Id

Hay varias formas de verificar la existencia de una columna. Recomiendo utilizar INFORMATION_SCHEMA.COLUMNS medida que se crea para comunicarse con el usuario. Considere seguir tablas:

  sys.objects sys.columns 

e incluso algunos otros métodos de acceso disponibles para verificar el system catalog.

Además, no es necesario usar SELECT * , simplemente NULL value por NULL value

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

Otra variación más …

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