Как проверить, существует ли столбец в таблице SQL Server?
Мне нужно добавить столбец, если он не существует. У меня что-то вроде следующего, но он всегда возвращает false:
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'myTableName'
AND COLUMN_NAME = 'myColumnName')
Как я могу проверить, существует ли столбец в таблице базы данных SQL Server?
23 ответа:
SQL Server 2005 и далее:
IF EXISTS(SELECT 1 FROM sys.columns WHERE Name = N'columnName' AND Object_ID = Object_ID(N'schemaName.tableName')) BEGIN -- Column Exists END
версия Мартина Смита короче:
IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL BEGIN -- Column Exists END
более сжатая версия
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
пункт о разрешениях на просмотр метаданных применяется ко всем ответам, а не только к этому.
обратите внимание, что первый параметр-имя таблицы
COL_LENGTH
может быть в одном, двух или трех формате имени части по мере необходимости.пример ссылки на таблицу в другой базе данных
COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate')
одно различие с этим ответом по сравнению с использованием представлений метаданных заключается в том, что функции метаданных например,
COL_LENGTH
всегда возвращайте только данные о зафиксированных изменениях, независимо от действующего уровня изоляции.
настройки ниже, чтобы удовлетворить ваши конкретные требования:
if not exists (select column_name from INFORMATION_SCHEMA.columns where table_name = 'MyTable' and column_name = 'MyColumn') alter table MyTable add MyColumn int
редактировать, чтобы иметь дело с edit to question: Это должно работать-внимательно просмотрите свой код для глупых ошибок; вы запрашиваете INFORMATION_SCHEMA в той же базе данных, к которой применяется ваша вставка, например? У вас есть опечатка в имени таблицы/столбца в любом операторе?
попробуйте это...
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
Я бы предпочел
INFORMATION_SCHEMA.COLUMNS
над системной таблицей, потому что Microsoft не гарантирует сохранение системных таблиц между версиями. Например,dbo.syscolumns
все еще работает в SQL 2008, но он устарел и может быть удален в любое время в будущем.
вы можете использовать системные представления информационной схемы, чтобы узнать почти все о таблицах, которые вас интересуют:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'yourTableName' ORDER BY ORDINAL_POSITION
вы также можете допрашивать представления, хранимые процедуры и почти все о базе данных, используя представления information_schema.
сначала проверьте, если
table
/column
(id
/name
) комбинация существует вdbo.syscolumns
(внутренняя таблица SQL Server, содержащая определения полей), и если не выдать соответствующийALTER TABLE
запрос, чтобы добавить его. Например:IF NOT EXISTS ( SELECT * FROM syscolumns WHERE id = OBJECT_ID('Client') AND name = 'Name' ) ALTER TABLE Client ADD Name VARCHAR(64) NULL
попробуйте что-то вроде:
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
тогда используйте его так:
IF ColumnExists('xxx', 'yyyy') = 'F' BEGIN ALTER TABLE xxx ADD yyyyy varChar(10) NOT NULL END GO
Он должен работать как сервер SQL 2000 и SQL сервер 2005. Не уверен в SQL Server 2008, но не вижу, почему бы и нет.
для людей, которые проверяют существование столбца, чтобы отбросить его.
на SQL Server 2016 вы можете использовать новые операторы DIE вместо big
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
мой хороший друг и коллега показал мне, как вы также можете использовать
IF
блок с функциями SQLOBJECT_ID
иCOLUMNPROPERTY
В SQL SERVER 2005+ для проверки столбца. Вы можете использовать что-то похожее на следующее: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:
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'table_name' AND column_name = 'column_name' ) BEGIN ... END
попробуй такое
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+.
Если это поможет кому-то еще, это то, что сработало для меня в конце концов:
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='<table_name>' and COLUMN_NAME='<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'
временная версия таблицы принято отвечать:
if (exists(select 1 from tempdb.sys.columns where Name = 'columnName' and Object_ID = object_id('tempdb..#tableName'))) begin ... end
ответ Wheat хорош, но предполагает, что у вас нет одинаковых пар имя таблицы / имя столбца в любой схеме или базе данных. Чтобы сделать его безопасным для этого условия, используйте это...
select * from Information_Schema.Columns where Table_Catalog = 'DatabaseName' and Table_Schema = 'SchemaName' and Table_Name = 'TableName' and Column_Name = 'ColumnName'
одним из самых простых и понятных решений является:
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
вот простой скрипт, который я использую для управления добавлением столбцов в базу данных:
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
в этом примере
Name
этоColumnName
иObject_Id
- этоTableName
есть несколько способов проверить существование столбца. Я настоятельно рекомендую использовать
INFORMATION_SCHEMA.COLUMNS
так как он создан для того, чтобы общаться с пользователем. Рассмотрим следующие таблицы:sys.objects sys.columns
и даже некоторые другие методы доступа, доступные для проверки
system catalog.
кроме того, нет необходимости использовать
SELECT *
, просто проверить его с помощьюNULL value
IF EXISTS( SELECT NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'myTableName' AND COLUMN_NAME = 'myColumnName' )