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

doe*_*dos 78 sql sql-server-2008

如何使用等于现有列的值的默认值将列添加到SQL Server表?

我试过这个T-SQL语句:

ALTER TABLE tablename 
ADD newcolumn type NOT NULL DEFAULT (oldcolumn) 
Run Code Online (Sandbox Code Playgroud)

但它给出了一个错误:

在此上下文中不允许使用"oldcolumn"这个名称.有效表达式是常量,常量表达式和(在某些上下文中)变量.不允许使用列名.

Kap*_*wal 63

试试这个:

ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go
Run Code Online (Sandbox Code Playgroud)

  • 这会在表上添加可能无意的默认约束 (10认同)
  • ..yes,但这只适用于现有的行.插入新行时,不会设置[newcolumn]值.您需要AFTER INSERT触发器等. (3认同)
  • @RomainVergnory 我同意,最好先不限制 NOT NULL,然后使用现有列填充值,然后再次添加 NOT NULL (2认同)

ype*_*eᵀᴹ 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   
Run Code Online (Sandbox Code Playgroud)


Her*_*Kan 11

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
Run Code Online (Sandbox Code Playgroud)

如果它oldcolumn是一个自动标识列,这不起作用.

  • `INSTEAD OF` 触发器在使用临时表时也不起作用:`SYSTEM_VERSIONING = ON` (2认同)

Vij*_*jai 10

您可以使用计算列根据现有列值在表中插入新列

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn) PERSISTED;
Run Code Online (Sandbox Code Playgroud)

或者,如果您想根据现有列值对值进行一些更改,请使用

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn * 1.5) PERSISTED;
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是正确的答案,官方答案只更新一次,正确的方法是使其长期一致 (2认同)
  • 虽然这并不是将 col2 默认为 f(col1),而是强制它。正确的默认行为是,如果 col2 为 null,则将其设置为 f(col1),否则使用 col2 中的 val。 (2认同)

小智 7

要扩展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
Run Code Online (Sandbox Code Playgroud)

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