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

时间:2012-11-06 11:21:52

标签: sql sql-server-2008

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

我尝试了这个T-SQL语句:

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

但是它给出了一个错误:

  

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

8 个答案:

答案 0 :(得分:59)

试试这个:

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

答案 1 :(得分:14)

我不太喜欢他们,但是你可以通过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   

答案 2 :(得分:9)

由于额外的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是自动标识列,则无效。

答案 3 :(得分:2)

要扩展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,或者其他类型的任何兼容数据,请将'no99'替换为'noData':具体值无关紧要,它将被第二条指令擦除。

答案 4 :(得分:0)

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

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

或者,如果您根据现有列值进行更改,则

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

答案 5 :(得分: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])

答案 6 :(得分:0)

使用计算列,它甚至可以处理 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;

产生以下结果:

Results as Grid

答案 7 :(得分:-3)

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