How to check if a column exists in a SQL Server table?
如果不存在,我需要添加一个特定的列。我有如下的东西,但它总是返回错误:
1 2 3 4 | IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'myTableName' AND COLUMN_NAME = 'myColumnName') |
如何检查SQL Server数据库的表中是否存在列?
SQL Server 2005之后的版本:
1 2 3 4 5 6 | IF EXISTS(SELECT 1 FROM sys.columns WHERE Name = N'columnName' AND Object_ID = Object_ID(N'schemaName.tableName')) BEGIN -- Column Exists END |
马丁·史密斯的版本较短:
1 2 3 4 | IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL BEGIN -- Column Exists END |
更简洁的版本
1 2 3 4 | 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 |
关于查看元数据的权限的要点适用于所有答案,而不仅仅是这个答案。
注意,
引用不同数据库中的表的示例是
1 | COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate') |
与使用元数据视图相比,此答案的一个不同之处在于,元数据函数(如
根据您的具体要求调整以下内容:
1 2 3 4 5 6 7 8 | if not exists (select column_name from INFORMATION_SCHEMA.columns where table_name = 'MyTable' and column_name = 'MyColumn') alter table MyTable add MyColumn int |
编辑来处理编辑到问题:这应该有效-仔细检查代码是否有愚蠢的错误;例如,您在应用插入的同一数据库上查询信息模式吗?在这两条语句中,您的表/列名称是否有错别字?
试试这个…
1 2 3 4 5 6 7 8 9 10 | 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 |
我更喜欢
您可以使用信息模式系统视图查找有关您感兴趣的表的几乎所有信息:
1 2 3 4 | SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'yourTableName' ORDER BY ORDINAL_POSITION |
您还可以使用信息模式视图查询视图、存储过程以及几乎所有有关数据库的内容。
首先检查
1 2 3 4 5 6 | IF NOT EXISTS ( SELECT * FROM syscolumns WHERE id = OBJECT_ID('Client') AND name = 'Name' ) ALTER TABLE Client ADD Name VARCHAR(64) NULL |
尝试以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
然后这样使用:
1 2 3 4 5 6 | IF ColumnExists('xxx', 'yyyy') = 'F' BEGIN ALTER TABLE xxx ADD yyyyy varChar(10) NOT NULL END GO |
它应该同时在SQL Server 2000和SQL Server 2005上工作。不确定SQL Server 2008,但不知道为什么。
对于检查列是否存在的人来说,删除它。
在SQL Server 2016中,可以使用新的die语句,而不是大的
1 | ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
我的一位好朋友和同事向我展示了如何在SQL Server 2005+中使用带有SQL函数
你可以在这里亲眼看到
1 2 3 4 5 | 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 |
这在SQL 2000中对我很有用:
1 2 3 4 5 6 7 8 9 10 | IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'table_name' AND column_name = 'column_name' ) BEGIN ... END |
试试这个
1 2 3 4 5 | 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') |
我需要类似的SQL Server 2000,正如@mitch指出的,这只在2005+中有效。
如果它能帮助其他人,这就是我最终的工作:
1 2 3 4 5 6 7 8 | if exists ( select * from sysobjects, syscolumns where sysobjects.id = syscolumns.id and sysobjects.name = 'table' and syscolumns.name = 'column') |
1 2 3 4 5 6 7 8 9 10 | 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 |
1 2 3 4 5 6 7 8 9 | 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; |
接受答案的临时表版本:
1 2 3 4 5 6 7 | if (exists(select 1 from tempdb.sys.columns where Name = 'columnName' and Object_ID = object_id('tempdb..#tableName'))) begin ... end |
1 2 3 | select distinct object_name(sc.id) from syscolumns sc,sysobjects so where sc.name like '%col_name%' and so.type='U' |
麦氏的答案是好的,但假设在任何模式或数据库中没有任何相同的表名/列名对。为了使它在这种情况下安全,使用这个…
1 2 3 4 5 6 | select * from Information_Schema.Columns where Table_Catalog = 'DatabaseName' and Table_Schema = 'SchemaName' and Table_Name = 'TableName' and Column_Name = 'ColumnName' |
有几种方法可以检查列的存在。我强烈建议使用
1 2 | sys.objects sys.columns |
甚至还有其他一些可用于检查
另外,无需使用
1 2 3 4 5 6 7 | IF EXISTS( SELECT NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'myTableName' AND COLUMN_NAME = 'myColumnName' ) |
下面是一个简单的脚本,用于管理数据库中列的添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
在这个例子中,
最简单易懂的解决方案之一是:
1 2 3 4 5 6 7 8 | 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 |
下面的查询可用于检查表中是否存在搜索列。我们可以根据搜索结果做出决定,如下所示。
1 2 3 4 5 6 7 8 | 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 |
还有另一个变种…
1 2 3 4 5 6 7 | SELECT Count(*) AS existFlag FROM sys.columns WHERE [name] = N 'ColumnName' AND [object_id] = OBJECT_ID(N 'TableName') |
1 2 3 | IF EXISTS(SELECT 1 FROM sys.columns WHERE Name = N'columnName' AND Object_ID = Object_ID(N'schemaName.tableName')) |
This should be the fairly easier way and straight forward solution to this problem. I have used this multiple times for similar scenarios. It works like a charm, no doubts on that.