Add a column to a table with a default value equal to the value of an existing column

如何将默认值等于现有列值的列添加到 SQLServer 表中?

I tried this T-SQL statement:

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

但它给出了一个错误:

在此上下文中不允许使用“ oldcolumn”名称 表达式是常量,常量表达式,和(在一些 contexts) variables. Column names are not permitted.

120374 次浏览

试试这个:

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

我不是很喜欢它们,但是你可以用 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

由于额外的 UPDATE语句,AFTER INSERT触发器方法涉及开销。我建议使用 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是一个自动标识列,那么这就不起作用了。

我认为如果您使用 Set Identity_Insert <TableName> OFF,并且在您编写的插入语句之后使用 Set Identity_Insert <TableName> ON,那么它将会工作。

要扩展 Kapil的答案,并避免不必要的默认约束,请尝试以下操作:

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

如果你的类型是 varchar,nvarchar,datetime,... 或者其他类型的任何兼容数据,将 -9999替换为‘ noData’: 具体的值并不重要,它将被第二条指令擦除。

可以使用计算列基于现有列值在表中插入新列

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

如果要基于现有列值对值进行某些更改,请使用

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

对于我的情况,我想添加一个名为 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])

使用计算列,它甚至可以处理 IDENTITY列值:

CREATE TABLE #This
( Id        INT IDENTITY(1,1)
,MyName    VARCHAR(10)
,FullName  AS (Myname + CONVERT(VARCHAR(10),Id)) PERSISTED);


INSERT #This VALUES ('Item'),('Item');


SELECT * FROM #This;


DROP TABLE #This;

yields the following:

Results as Grid