向表中添加一列,其默认值等于现有列的值


90

如何在默认值等于现有列值的情况下向SQL Server表中添加列?

我尝试了以下T-SQL语句:

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

但它给出了一个错误:

在这种情况下,不允许使用名称“ oldcolumn”。有效表达式是常量,常量表达式和(在某些情况下)变量。不允许使用列名。


6
默认值可以是常量,不能是另一列。我认为这需要一个触发器。
ypercubeᵀᴹ

1
好的,我该怎么做,我是sql的新手。
dodos 2012年

1
这将始终是默认值,还是仅用于在将新列添加到表时填充现有行的列?
Damien_The_Unbeliever 2012年

1
@Damien_The_Unbeliever仅用于填充现有行的列。
dodos 2012年

2
UPDATE恐怕您必须单独进行此操作。
Damien_The_Unbeliever 2012年

Answers:


73

试试这个:

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

5
..是,但这仅适用于现有行。插入新行时,它不会设置[newcolumn]值。您需要AFTER INSERT触发器等等
米兰

14
这会在表上添加一个可能意外的默认约束
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   

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

要扩展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”:特定值无关紧要,它将被第二条指令擦除。


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并且在您编写的insert语句之后使用,它会起作用Set Identity_Insert <TableName> ON

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.