Мне нужно добавить конкретный столбец, если он не существует. У меня есть что-то вроде следующего, но он всегда возвращает false:
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'myTableName'
AND COLUMN_NAME = 'myColumnName')
Как я могу проверить, существует ли столбец в таблице базы данных SQL Server?
32 ответа
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
sys.columns
IS NOT NULL
не >0
Более лаконичная версия
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 OBJECT_ID('TableName','U') IS NULL
для проверки существования объекта или DB_ID('foo')
для проверки существования базы данных.
x>>2
вместо x/4
в C ++. Более подробный код (if exists (select column_name from information_schema ...)
) занимает намного больше места, но никто бы никогда не стал чесать в затылке, пытаясь понять, что он делает.
INFORMATION_SCHEMA
или sys.columns
попадает на диск, в то время как COL_LENGTH
использует кэшированные метаданные базы данных.
Попробуй это...
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
SELECT 1
вместо SELECT TOP 1 1
;).
EXISTS
SQL автоматически оптимизирует столбцы (так же, как count(*)
), так что SELECT *
будет достаточно.
and [TABLE_SCHEMA] = '???'
в предложение WHERE.
Для людей, которые проверяют наличие столбца перед тем, как его выбросить.
Начиная с SQL Server 2016, вы можете использовать новые операторы DIE (Drop If Exists) вместо больших оболочек IF
.
ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
Я бы предпочел INFORMATION_SCHEMA.COLUMNS
системной таблице, потому что Microsoft не гарантирует сохранение системных таблиц между версиями. Например, dbo.syscolumns
по-прежнему работает в SQL Server 2008, но он устарел и может быть удален в любое время в будущем.
INFORMATION_SCHEMA
содержат только метаданные стандарта ANSI. Однако этого достаточно для проверки существования.
Вы можете использовать системные представления информационной схемы, чтобы узнать практически все о таблицах, которые вас интересуют:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yourTableName'
ORDER BY ORDINAL_POSITION
Вы также можете запрашивать представления, хранимые процедуры и многое другое о базе данных, используя представления Information_schema.
Попробуйте что-нибудь вроде:
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 Server 2000, так и на SQL Server 2005. Я не уверен в SQL Server 2008, но не понимаю, почему бы и нет.
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 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')
INFORMATION_SCHEMA.TABLES
, и вы не фильтруете столбцы для определенной таблицы, поэтому иногда он возвращает более одной строки для тех же имен столбцов в отдельных таблицах;).
select *
from Information_Schema.Columns
where Table_Catalog = 'DatabaseName'
and Table_Schema = 'SchemaName'
and Table_Name = 'TableName'
and Column_Name = 'ColumnName'
Проверить наличие столбца можно несколькими способами. Я настоятельно рекомендую использовать 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'
)
SELECT *
с EXISTS
, потому что, когда существует, он на самом деле не выбирает все строки и все столбцы, внутренне он просто проверяет наличие, а не фактически проверяет все строки и колонны
Одним из самых простых и понятных решений является:
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
Сделайте что-нибудь, если столбец не существует:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
BEGIN
// Do something
END
END;
Сделайте что-нибудь, если столбец существует:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
BEGIN
// Do something
END
END;
Еще одна вариация ...
SELECT
Count(*) AS existFlag
FROM
sys.columns
WHERE
[name] = N 'ColumnName'
AND [object_id] = OBJECT_ID(N 'TableName')
Сначала проверьте, существует ли комбинация 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
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 exist in table
END
Таблица -> таблица скриптов как -> новые окна - у вас есть дизайн-скрипт. проверьте и найдите имя столбца в новых окнах
Мой хороший друг и коллега показал мне, как можно использовать блок IF
с функциями SQL OBJECT_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
COLUMNPROPERTY
.
Еще одним вкладом является следующий пример, который добавляет столбец, если он не существует.
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
Вы можете одновременно проверить несколько столбцов в SQLDB и вернуть строку в качестве статуса, чтобы проверить, существуют ли столбцы:
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Table Name'
AND(COLUMN_NAME = 'column 1'
or COLUMN_NAME = 'column 2'
or COLUMN_NAME = 'column 3'
or COLUMN_NAME = 'column 4')
)
SELECT 'Column exists in table' AS[Status];
ELSE
SELECT 'Column does not exist in table' AS[Status];
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'columnName'
AND Object_ID = Object_ID(N'schemaName.tableName'))
Это должно быть довольно простым способом и простым решением этой проблемы. Я использовал это несколько раз для подобных сценариев. Он работает как шарм, в этом нет никаких сомнений.
Приведенный ниже запрос можно использовать для проверки того, существует ли искомый столбец в таблице. Мы можем принять решение на основе результатов поиска, как показано ниже.
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
//Only checks
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
Мне нужно было что-то подобное для SQL Server 2000 и, поскольку Митч указывает, это работает только в SQL Server 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 exist'
end
Временная табличная версия принятого ответа:
if (exists(select 1
from tempdb.sys.columns
where Name = 'columnName'
and Object_ID = object_id('tempdb..#tableName')))
begin
...
end
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;
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so
where sc.name like '%col_name%' and so.type='U'
Выполните приведенный ниже запрос, чтобы проверить, существует ли столбец в данной таблице:
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';
Измените нижеприведенное в соответствии с вашими конкретными требованиями:
if not exists (select
column_name
from
INFORMATION_SCHEMA.columns
where
table_name = 'MyTable'
and column_name = 'MyColumn')
alter table MyTable add MyColumn int
Это должно сработать - внимательно просмотрите свой код на наличие глупых ошибок; вы запрашиваете INFORMATION_SCHEMA в той же базе данных, к которой, например, применяется ваша вставка? У вас есть опечатка в имени таблицы/столбца в любом из утверждений?
Похожие вопросы
Связанные вопросы
Новые вопросы
sql-server
Microsoft SQL Server — это система управления реляционными базами данных (RDBMS). Используйте этот тег для всех выпусков Microsoft SQL Server, включая Compact, Express, Azure, Fast-track, APS (ранее PDW) и Azure SQL DW. Не используйте этот тег для других типов СУБД (MySQL, PostgreSQL, Oracle и т. д.). Не используйте этот тег для вопросов по программному обеспечению и разработке мобильных устройств, если только он не связан напрямую с базой данных.
COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')
работает нормально.EXEC sp_executesql
с сформированным операторомUPDATE
.FROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS