110

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

我试过这个 T-SQL 语句:

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

但它给出了一个错误:

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

4

8 回答 8

87

试试这个:

ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go
于 2012-11-06T11:25:56.130 回答
17

由于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如果是自动标识列,这将不起作用。

于 2014-09-09T09:19:13.283 回答
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   
于 2012-11-06T11:40:37.367 回答
5

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

于 2017-04-21T15:57:55.240 回答
3

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

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

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

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn * 1.5) PERSISTED;
于 2019-07-26T17:01:40.290 回答
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])
于 2019-11-04T07:35:43.367 回答
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;

产生以下结果:

结果为网格

于 2021-05-21T15:42:12.073 回答
-3

我认为如果您使用Set Identity_Insert <TableName> OFF并且在您编写的插入语句之后使用Set Identity_Insert <TableName> ON.

于 2016-10-19T07:54:45.767 回答