Як перевірити, чи існує стовпець у таблиці 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.