Добавить столбец в таблицу со значением по умолчанию, равным значению существующего столбца

94

Как добавить столбец в таблицу SQL Server со значением по умолчанию, равным значению существующего столбца?

Я пробовал этот оператор T-SQL:

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

но это дает ошибку:

Имя "oldcolumn" в этом контексте недопустимо. Допустимые выражения - это константы, константные выражения и (в некоторых контекстах) переменные. Имена столбцов не разрешены.

dodos
источник
6
Значение по умолчанию может быть константой, а не другим столбцом. Думаю, для этого нужен спусковой крючок.
ypercubeᵀᴹ
1
хорошо, как я могу это сделать, я новичок в sql.
dodos 06
1
Всегда ли это будет значение по умолчанию или это просто для заполнения столбца для существующих строк, пока новый столбец добавляется в таблицу?
Damien_The_Unbeliever
1
@Damien_The_Unbeliever только для заполнения столбца для существующих строк.
dodos 06
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
Капил Хандельвал
источник
6
..да, но это будет работать только для существующих строк. Он не будет устанавливать значение [newcolumn] при вставке новых строк. Вам нужен триггер AFTER INSERT и т. Д.
Милан,
16
Это добавляет, возможно, непреднамеренное ограничение по умолчанию для таблицы
Romain Vergnory
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   
ypercubeᵀᴹ
источник
15

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
1
Триггер «Вместо вставки» является правильным ответом, если только столбец, который вы хотите использовать для значения по умолчанию, не является столбцом идентификаторов, как упоминалось выше, поскольку триггеры «Вместо» выполняются до (и отвечают за выполнение) вставки таблицы и столбцов идентификаторов не получить автоматические значения, пока не произойдет вставка. Я не знаю другого способа сделать один столбец значением по умолчанию для другого столбца при вставке записи, если столбец определен как ненулевой без начального значения по умолчанию.
Чак Бевитт
4

Чтобы расширить ответ Капила и избежать нежелательного ограничения по умолчанию, попробуйте следующее:

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, ... или любые совместимые данные для других типов: конкретное значение не имеет значения, оно будет стерто второй инструкцией.

Фредерик Шовьер
источник
2

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

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])
Trần Thanh Phong
источник
-3

Я думаю, что это сработает, если вы используете Set Identity_Insert <TableName> OFFи после написанного вами оператора вставки просто используйте Set Identity_Insert <TableName> ON.

user7040891
источник