Додайте стовпчик до таблиці, якщо він ще не існує


188

Я хочу написати запит для MS SQL Server, який додає стовпець у таблицю. Але я не хочу відображати помилки під час запуску / виконання наступного запиту.

Я використовую такий тип запиту, щоб додати таблицю ...

IF EXISTS (
       SELECT *
       FROM   sys.objects
       WHERE  OBJECT_ID = OBJECT_ID(N'[dbo].[Person]')
              AND TYPE IN (N'U')
   )

Але я не знаю, як написати цей запит для стовпця.



Ви повинні використовувати sys.tablesзамість "generic" sys.objects- тоді вам не доведеться чітко вказувати тип (це очевидно з sys.tablesуже ....)
marc_s

COL_LENGTH Альтернатива працює лише з SQL-Server 2008, але вона працює.
Пол-Анрі

Відповіді:


219

Можна використовувати аналогічну конструкцію, використовуючи sys.columnsтаблицю io sys.objects.

IF NOT EXISTS (
  SELECT * 
  FROM   sys.columns 
  WHERE  object_id = OBJECT_ID(N'[dbo].[Person]') 
         AND name = 'ColumnName'
)

42
Зауважте, що в цьому випадку ви хочете використовувати ІЗ НЕ ІСНУЄТЬСЯ у фактичному коді.
Нат

2
Для оптимізованого запиту ви можете скористатись першою топ-
версією

11
@BanketeshvarNarayan це неправильно. Плани виконання підзапитів у EXISTSпункті ідентичні. Речі на кшталт SELECT 1або SELECT TOP 1непотрібні. Сам EXISTSпункт повідомляє оптимізатору запитів виконувати лише мінімальний зчитування, необхідний для оцінки EXISTS... принаймні в SQL Server. Інші двигуни БД можуть мати більш-менш ефективний оптимізатор запитів.
Кеннет Кокран

9
@BanketeshvarNarayan Якщо ви оптимізуєте свої ADD Columnзапити ... ви повинні запускати їх занадто часто!
Фентон

1
@ user391339 - Я опублікував аналогічну конструкцію, що і ОП, але так, якщо ви хочете вжити заходів, якщо стовпець не існує, заява буде ЯКЩО НЕ існує. Я не відчуваю необхідності редагувати відповідь на це, але не соромтесь редагувати себе, якщо ви думаєте, що це покращення.
Лівен Кірсмейкер

91
IF COL_LENGTH('table_name', 'column_name') IS NULL
BEGIN
    ALTER TABLE table_name
    ADD [column_name] INT
END

1
Я спробував це зробити, але він повертає помилку, яка стверджує, що функція COL_LENGTH не існує.
ThEpRoGrAmMiNgNoOb

3
Потрібен SQL Server 2008+
Роберт Браун

6
Невелике доповнення - не слід використовувати квадратні дужки у назві стовпців, оскільки COL_LENGTH('table_name', '[column_name]')завжди повертайте null у SQL Server 2016 ( COL_LENGTH('[table_name]', 'column_name') works as expected).
стоп-кран

33

Ще одна альтернатива. Я віддаю перевагу такому підходу, оскільки це менше писати, але двоє досягають одного і того ж.

IF COLUMNPROPERTY(OBJECT_ID('dbo.Person'), 'ColumnName', 'ColumnId') IS NULL
BEGIN
    ALTER TABLE Person 
    ADD ColumnName VARCHAR(MAX) NOT NULL
END

Я також помітив, що ваша шукає, де існує стіл, що, очевидно, саме це

 if COLUMNPROPERTY( OBJECT_ID('dbo.Person'),'ColumnName','ColumnId') is not null

2
Мені це подобається. Я думаю, що найкраща частина розміщення тут - це пошук таких дорогоцінних каменів.
JStead

2
Що таке "ColumnId"?
Маріус

"ColumnId" - це назва властивості стовпця, проти якого ви перевіряєте. Напевно, ви могли використовувати будь-яке ім’я властивості, яке існує у стовпці, наприклад, ім’я тощо.
Jacques Bosch

5

Ось ще одна варіація, яка працювала на мене.

IF NOT EXISTS (SELECT 1
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE upper(TABLE_NAME) = 'TABLENAME'
        AND upper(COLUMN_NAME) = 'COLUMNNAME')
BEGIN
    ALTER TABLE [dbo].[Person] ADD Column
END
GO

EDIT: Зауважте, що INFORMATION_SCHEMAпредставлення даних не завжди може оновлюватися SYS.COLUMNS.

IF NOT EXISTS (SELECT 1 FROM SYS.COLUMNS....


0
IF NOT EXISTS (SELECT * FROM syscolumns
  WHERE ID=OBJECT_ID('[db].[Employee]') AND NAME='EmpName')
  ALTER TABLE [db].[Employee]
  ADD [EmpName] VARCHAR(10)
GO

Сподіваюся, це допоможе. Більше інформації


Це працювало для мене на SqlServer 2000, тоді як прийнята відповідь не відповіла. Здається, погляди sys. * Були додані десь біля SqlServer 2005, пор. docs.microsoft.com/en-us/sql/relational-databases/…
ZeRemz

0

Перевіряючи наявність стовпця в іншій базі даних, ви можете просто включити ім'я бази даних:

IF NOT EXISTS (
  SELECT * 
  FROM   DatabaseName.sys.columns 
  WHERE  object_id = OBJECT_ID(N'[DatabaseName].[dbo].[TableName]') 
         AND name = 'ColumnName'
)

-1
IF NOT EXISTS (SELECT 1  FROM SYS.COLUMNS WHERE  
OBJECT_ID = OBJECT_ID(N'[dbo].[Person]') AND name = 'DateOfBirth')
BEGIN
ALTER TABLE [dbo].[Person] ADD DateOfBirth DATETIME
END
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.