简体   繁体   English

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

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

How to add a column to a SQL Server table with a default value that is equal to value of an existing column?如何将默认值等于现有列值的列添加到 SQL Server 表中?

I tried this T-SQL statement:我试过这个 T-SQL 语句:

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

but it's giving an error:但它给出了一个错误:

The name "oldcolumn" is not permitted in this context.在此上下文中不允许使用名称“oldcolumn”。 Valid expressions are constants, constant expressions, and (in some contexts) variables.有效表达式是常量、常量表达式和(在某些上下文中)变量。 Column names are not permitted.列名是不允许的。

Try this:试试这个:

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

The AFTER INSERT trigger approach involves overhead due to the extra UPDATE statement.由于额外的UPDATE语句, AFTER INSERT触发器方法涉及开销。 I suggest using an INSTEAD OF INSERT trigger, as follows:我建议使用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

This does not work though if the oldcolumn is an auto-identity column.如果oldcolumn列是自动标识列,则这不起作用。

I don't like them very much but here is how you could do this with an AFTER INSERT trigger:我不太喜欢它们,但这是使用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   

You can use computed column to insert new column in a table based on an existing column value您可以使用计算列根据现有列值在表中插入新列

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

OR, if you want to make some changes to the value based on existing column value, use或者,如果您想根据现有列值对值进行一些更改,请使用

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

To extend Kapil 's answer, and avoid the unwanted default constraint, try this:要扩展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

Replace -9999 by 'noData' if your type is varchar, nvarchar, datetime,... or by any compatible data for other types: specific value doesn't matter, it will be wiped by the 2nd instruction.如果您的类型是 varchar、nvarchar、datetime 等,请将 -9999 替换为“noData”,或者替换为其他类型的任何兼容数据:具体值无关紧要,它将被第二条指令擦除。

For my case, I want to add a new not null unique column named CODE but I don't know about the value at the creation time.对于我的情况,我想添加一个名为 CODE 的新非空唯一列,但我不知道创建时的值。 I set the default value for it by get a default value from NewID() then update later.我通过从 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])

Use a computed column, which will even work with IDENTITY column values:使用计算列,它甚至可以使用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:产生以下内容:

结果作为网格

I think it will work if you use Set Identity_Insert <TableName> OFF and after the insert Statement that you wrote just use Set Identity_Insert <TableName> ON .我认为如果您使用Set Identity_Insert <TableName> OFF并且在您编写的插入语句之后只使用Set Identity_Insert <TableName> ON ,它将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM