Як перевірити, чи існує стовпець у таблиці SQL Server?


1853

Мені потрібно додати певний стовпець, якщо його не існує. У мене є щось на кшталт наступного, але воно завжди повертає помилкове:

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

Як я можу перевірити наявність стовпця в таблиці бази даних SQL Server?


12
Я насправді не думаю, що з кодом у питанні нічого поганого: Мені непогано працює у R2 2008 року. (Можливо, ви працювали в неправильній базі даних? Можливо, у вашій базі даних було чутливим до регістру, і у вас не було правильного випадку в рядках myTableName / myColumnName? Цей тип запиту здається більш гнучким, ніж рішення COL_LENGTH: я вмію щоб запустити його на іншій базі даних і навіть через посилання на базу даних, відповідним чином встановивши приставку "INFORMATION_SCHEMA". Неможливо зрозуміти, як це зробити з метаданими-функцією
— COL_LENGTH

3
@mwardm - COL_LENGTH('AdventureWorks2012.HumanResources.Department ','ModifiedDate')прекрасно працює.
— Мартін Сміт

6
Невеликий пов’язаний натяк: якщо ви хочете оновити стовпчик відразу після додавання стовпця (я вважаю, що багато користувачів шукали цю статтю для цієї мети), ви можете скористатися EXEC sp_executesqlсформованим UPDATEоператором.
— кассандрад

Справжня відповідь: ви повинні додати базу даних, на яку ви перевіряєте, так цеFROM [YourDatabase].INFORMATION_SCHEMA.COLUMNS
— Алекс Квітний,

Відповіді:


2054

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

У версії Мартіна Сміта слід згадати одне, що не включати стовпчик у квадратні дужки []. Якщо колонка має всередині квадратних дужок [], вона видасть нуль, навіть якщо стовпець існує в таблиці
— Hemendra

@HemendraSinghChauhan - це тому, що вони не входять до назви. Ви також побачите, що, порівнюючи його з ім'ямsys.columns
— Мартін Сміт,

@MartinSmith цього не знав, я використовував вашу відповідь і натрапив на це. Як правило, я використовую квадратні дужки під час додавання стовпців, тому я використовував їх і у функції COL_LENGTH. Мій код був такий:Alter table Table_Name Add [ColumnName] NVarchar(max) NULL; Select COL_LENGTH('[TABLE_NAME]', '[COLUMN_NAME]')
— Hemendra

так, це не вірно. Аргументи COL_LENGTHпотрібно не цитувати. Теоретично можливо, щоб хтось створив стовпчик, який насправді має назву [COLUMN_NAME]- наприклад, CREATE TABLE #T([[COLUMN_NAME]]] INT); SELECT * FROM #Tі тоді було б неоднозначно, якби це не було правилом.
— Мартін Сміт

987

Більш стисла версія

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завжди, лише повертають дані про здійснені зміни незалежно від рівня ізоляції, що діє.


11
Це менш читабельно, ніж деякі інші відповіді, ймовірно, чому це не так високо оцінено.
— Білл Ян

38
@Bill - Менш читабельним способом? Чудово виглядає у Firefox. Ця відповідь була опублікована більш ніж на 2 роки пізніше прийнятої, що пояснює рейтинг IMO. Якщо ви мали на увазі менш зрозуміло, що це перевірка існування, такий тип ідіоми є досить поширеним у SQL Server. наприклад, IF OBJECT_ID('TableName','U') IS NULLдля перевірки існування об'єкта або DB_ID('foo')для перевірки наявності бази даних.
— Мартін Сміт

59
@MartinSmith Я впевнений, що він мав на увазі менш читабельний, тому що якби ти не знав цієї ідіоми, і ти успадкував цей код від когось іншого, ти не одразу зрозумів би, що робить код. Начебто як писати x>>2замість x/4C ++. Більш багатослівний код ( if exists (select column_name from information_schema ...)) займає набагато більше місця, але ніхто ніколи не почухає голову, намагаючись зрозуміти, що це робить.
— Кіп

22
Крім більш стислого, це спосіб швидшого рішення. Доступ до INFORMATION_SCHEMAпредставлень даних або sys.columnsпотрапляє на диск, COL_LENGTHвикористовуючи кешовані метадані бази даних.
— wqw

7
Це, мабуть, не найвище оцінена відповідь, оскільки вона була надана через 2,5 роки після другої. Тому я завжди перевіряю дати, порівнюючи оцінки за двома відповідями. Щоб подолати відповідь, дану набагато раніше, потрібно набагато більше часу. ;)
— Шон

149

Налаштуйте наведене нижче, щоб відповідати вашим конкретним вимогам:

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 в тій самій базі даних, до якої, наприклад, застосовується ваша вставка? Чи є помилка друку у назві таблиці / стовпця в будь-якому виписці?


3
Я щойно з’ясував, що додаючи TABLE_SCHEMA = 'mySchema' після того, як стаття вирішує проблему.
— Мацей

12
-1: не відповідає на питання ОП, лише додає нову інформацію про те, як додати новий стовпчик, незважаючи на те, що ОП взагалі не питає про це, не звертається до коментарів ОП.
— ANeves

1
+1 Відповідає на питання ОП ідеально, бонус за додаткову інформацію, яку ОП збирає в наступному. І саме це я шукав.
— Bitterblue

74

Спробуйте це...

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
Цей метод також працює з SQL CE, тоді як деякі з інших згаданих методів цього не роблять.
— SWALters

9
Ви можете використовувати SELECT 1замість SELECT TOP 1 1;).
— shA.t

4
Всередині EXISTSоператора SQL автоматично оптимізує стовпці (начебто count(*)), тому SELECT *буде достатньо.
— Марк Л.

Для повноти слід розглянути питання про додавання and [TABLE_SCHEMA] = '???'до пункту WHERE.
— Ендрю Єнс

50

Люди, які перевіряють існування стовпця, скидають її.

З SQL Server 2016 ви можете використовувати нові заяви DIE замість великих IFобгортків

ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name

47

Я віддаю перевагу INFORMATION_SCHEMA.COLUMNSнад системною таблицею, оскільки Microsoft не гарантує збереження системних таблиць між версіями. Наприклад, dbo.syscolumnsвін все ще працює в SQL 2008, але він застарів і може бути видалений у будь-який час у майбутньому.



5
Ну так, це само собою зрозуміло, оскільки INFORMATION_SCHEMAпредставлення містять лише стандартні метадані ANSI. Однак цього достатньо для тесту на існування.
— Крістіан Хейтер

3
Microsoft говорить: "У майбутніх випусках SQL Server Microsoft може доповнити визначення будь-якого перегляду системного каталогу, додавши стовпці до кінця списку стовпців. Ми рекомендуємо не використовувати синтаксис SELECT * FROM sys.catalog_view_name у виробничому коді, оскільки кількість стовпці, що повернулися, можуть змінити та порушити вашу програму. " Це означає, що вони не видалятимуть стовпці та не змінюватимуть їх порядок. Це досить хороша відстала сумісність для всіх випадків, окрім крайових.
— siride

42

За допомогою системних представлень інформаційної схеми ви можете дізнатися майже все, що вас цікавить:

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

Ви також можете допитувати представлення даних, збережені процедури та багато чого іншого про базу даних, використовуючи представлення Information_schema.


Саме для цього використовується анкета, йому потрібно було знати, як додати стовпчик, якщо його не було.
— Бірель

35

Спробуйте щось на кшталт:

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, але не розумію, чому ні.


34

Спочатку перевірте, чи існує комбінація 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

28

Мій хороший друг і колега показав мені, як ви також можете використовувати 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

1
І звичайно, якщо ви впевнені, що таблиця існує, ви можете залишити першу частину умови та перевірити COLUMNPROPERTYлише.
— Рууд Гельдерман

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

Це працювало для мене в SQL 2000:

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

21

Спробуйте це

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і ви не фільтруєте стовпці за певною таблицею, тож іноді вони повертатимуть більше, ніж один рядок за однаковими назвами стовпців в окремих таблицях;).
— shA.t

19

Мені потрібно було подібне для SQL SERVER 2000, і, як вказує @Mitch, це працює лише в 2005 році.

Якщо це допоможе кому-небудь іншому, ось що, в кінцевому підсумку, спрацювало для мене:

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
Я думаю, ти мав на увазі table_schema = 'ім'я схеми'.
— Tab Alleman

11

Версія прийнятої відповіді щодо темпної таблиці :

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

1
Чим це відрізняється від прийнятої відповіді? Чи не працює таблиця темп у прийнятій відповіді?
— Джон Сондерс

1
Правильно. Прийнята відповідь не працює для тимчасових таблиць, оскільки 'sys.column' має бути вказано як 'tempdb.sys.column', а ім'я таблиці повинно бути попереднім 'tempdb ..'.
— крокусек

10
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so  
where sc.name like '%col_name%' and so.type='U'

8

Відповідь пшениці хороша, але припускає, що у вас немає жодної ідентичної пари імен таблиці / імен стовпців у будь-якій схемі чи базі даних. Щоб зробити це безпечним для цього стану, скористайтеся цим ...

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

8

Існує кілька способів перевірити наявність стовпця. Я настійно рекомендую використовувати так, 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'
         ) 

1
Не важливо, навіть якщо ви SELECT *використовуєте EXISTS, адже коли використовується, він насправді не вибирає всі рядки та всі стовпці, внутрішньо він просто перевіряє наявність, а фактично не перевіряє всі рядки та стовпці
— Pawan Nogariya

7

Одне з найбільш простих і зрозумілих рішень:

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

Ось простий скрипт, який я використовую для управління додаванням стовпців до бази даних:

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


4

Нижче запит може бути використаний для перевірки того, чи існує шуканий стовпець у таблиці. Ми можемо приймати рішення на основі результату пошуку, як показано нижче.

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

table -> table script як -> new windows - у вас є сценарій дизайну. перевірте та знайдіть назву стовпця у нових вікнах


1

Виконайте нижченаведений запит, щоб перевірити, чи існує стовпець у даній таблиці:

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

Інший внесок - наступний зразок, який додає стовпець, якщо його немає.

    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

Сподіваюся, це допомагає. Симона


0
IF EXISTS(SELECT 1 FROM sys.columns 
      WHERE Name = N'columnName'
      AND Object_ID = Object_ID(N'schemaName.tableName'))

Це має бути досить простим способом та прямим рішенням цієї проблеми. Я використовував це кілька разів для подібних сценаріїв. Це працює як шарм, у цьому немає сумнівів.


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

Зробіть щось, якщо стовпець не існує:

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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.