Додайте стовпець до таблиці зі значенням за замовчуванням, рівним значенню існуючого стовпця


90

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

Я спробував цей вираз T-SQL:

ALTER TABLE tablename 
ADD newcolumn type NOT NULL DEFAULT (oldcolumn) 

але це видає помилку:

Назва "стара колонка" в цьому контексті заборонена. Дійсні вирази - це константи, константні вирази та (у деяких контекстах) змінні. Назви стовпців заборонені.


6
Значенням за замовчуванням може бути константа, а не інший стовпець. Я думаю, для цього потрібен тригер.
ypercubeᵀᴹ

1
добре, як я можу це зробити, я новачок у sql.
dodos

1
Це завжди буде за замовчуванням, чи це просто для заповнення стовпця для існуючих рядків, коли новий стовпець додається до таблиці?
Damien_The_Unbeliever

1
@Damien_The_Unbeliever лише для заповнення стовпця для існуючих рядків.
dodos

2
UPDATEТоді, боюсь, це потрібно робити окремо .
Damien_The_Unbeliever

Відповіді:


73

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

ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go

5
.. Так, але це буде працювати лише для існуючих рядків. Він не встановить значення [newcolumn], коли будуть вставлені нові рядки. Вам потрібен ПІСЛЯ ВСТАВКИ тригер тощо
Мілан

14
Це додає можливе ненавмисне обмеження за замовчуванням у таблиці
Ромен Верньорі

1
@RomainVergnory Я згоден, краще спочатку перейти без обмеження на NOT NULL, потім заповнити значення наявним стовпцем, а пізніше знову додати NOT NULL
adkl

15

Вони мені не дуже подобаються, але ось як ви можете зробити це за допомогою AFTER INSERTтригера:

CREATE TRIGGER TableX_AfterInsert_TRG 
  ON TableX 
AFTER INSERT
AS
  UPDATE TableX AS t
  SET t.newcolumn = t.oldcolumn
  FROM Inserted AS i
  WHERE t.PK = i.PK ;              -- where PK is the PRIMARY KEY of the table   

13

AFTER INSERTТригер підхід включає в себе накладні витрати з - за додаткове UPDATEзаяву. Я пропоную використовувати INSTEAD OF INSERTтригер наступним чином:

CREATE TRIGGER tablename_on_insert ON tablename 
INSTEAD OF INSERT 
AS
INSERT INTO tablename (oldcolumn, newcolumn)
SELECT oldcolumn, ISNULL(newcolumn, oldcolumn)
FROM inserted

Однак це не працює, якщо oldcolumnстовпець автоідентифікації.


2
INSTEAD OFтригери також не працюють при використанні часових таблиць:SYSTEM_VERSIONING = ON
CalvinDale

3

Щоб розширити відповідь Капіла та уникнути небажаного обмеження за замовчуванням, спробуйте наступне:

ALTER TABLE tablename ADD newcolumn type NOT NULL CONSTRAINT DF_TMP_TABLENAME_NEWCOLUMN DEFAULT -9999
Go
Update tablename SET newcolumn = oldcolumn
Go
ALTER TABLE tablename DROP CONSTRAINT DF_TMP_TABLENAME_NEWCOLUMN
Go

Замініть -9999 на "noData", якщо ваш тип varchar, nvarchar, datetime, ... або на будь-які сумісні дані для інших типів: конкретне значення не має значення, воно буде видалено другою інструкцією.


1

Ви можете використовувати обчислюваний стовпець, щоб вставити новий стовпець у таблицю на основі існуючого значення стовпця

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn) PERSISTED;

АБО, якщо ви хочете внести деякі зміни у значення на основі існуючого значення стовпця, використовуйте

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn * 1.5) PERSISTED;

0

Для мого випадку я хочу додати новий не нульовий унікальний стовпець з назвою CODE, але я не знаю про значення на момент створення. Я встановив для нього значення за замовчуванням, отримавши значення за замовчуванням від NewID (), а потім оновити пізніше.

ALTER TABLE [WIDGET] ADD [CODE] CHAR(5) NOT NULL DEFAULT(SUBSTRING(CONVERT(CHAR(36), NEWID()), 1, 5))

ALTER TABLE [dbo].[WIDGET] WITH CHECK ADD CONSTRAINT [UQ_WIDGET_CODE] UNIQUE ([CODE])

-3

Я думаю, це буде працювати, якщо ви використовуєте Set Identity_Insert <TableName> OFFта після вставки Заява, яку ви просто написали, використовуєте Set Identity_Insert <TableName> ON.

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