如何在 SQL Server 的单个批次中为列添加默认值并使用默认值更新所有行?

Posted

技术标签:

【中文标题】如何在 SQL Server 的单个批次中为列添加默认值并使用默认值更新所有行?【英文标题】:How can I add a default for a column and update all rows with the default value in a single batch in SQL Server? 【发布时间】:2011-05-03 16:42:23 【问题描述】:

我正在尝试在事务中执行以下代码作为迁移的一部分,但除非我将GO 语句放在ADD CONSTRAINT 语句之后,否则代码会失败:

ALTER TABLE T ADD C INT NULL
ALTER TABLE T ADD CONSTRAINT DF_T_C DEFAULT ((1)) FOR C
GO 
UPDATE T SET C = DEFAULT
ALTER TABLE T ALTER COLUMN C INT NOT NULL

如果我省略 GO 语句,我会收到以下错误:

列名“C”无效。

执行迁移的代码无法处理GO 语句,我怎样才能让它在单个事务中工作?

【问题讨论】:

【参考方案1】:

您可以将EXEC 用于有问题的语句,以便将它们编译为不同的批处理。

EXEC('UPDATE T SET C = DEFAULT; 
      ALTER TABLE T ALTER COLUMN C INT NOT NULL')

但你也可以这样做

ALTER TABLE T ADD C INT NOT NULL CONSTRAINT DF_T_C DEFAULT ((1))

而不是自己完成所有这些单独的步骤。

【讨论】:

@michielvoo - 声明不仅接近而且完全正确! CREATE TABLE #T(B INT NULL);INSERT INTO #T VALUES (10);ALTER TABLE #T ADD C INT NOT NULL CONSTRAINT DF_T_C DEFAULT ((1));SELECT * FROM #T;DROP TABLE #T【参考方案2】:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET XACT_ABORT ON;

BEGIN TRANSACTION;

ALTER TABLE T ADD C INT NULL;

ALTER TABLE T ADD CONSTRAINT DF_T_C DEFAULT ((1)) FOR C;
EXEC ('UPDATE T SET C = DEFAULT');

ALTER TABLE T ALTER COLUMN C INT NOT NULL;

COMMIT TRANSACTION;

【讨论】:

【参考方案3】:

我最终得到了这个,它在一个语句中完成了所有事情:

ALTER TABLE T ADD C INT NOT NULL CONSTRAINT DF_T_C DEFAULT ((1)) WITH VALUES

适用于 SQL Server。

【讨论】:

WITH VALUES 仅在列为 NULL 时才需要,然后看起来您的脚本将其设置为 NOT NULL。我的回答中的陈述在一个陈述中完成了所有这些,并且避免了这样做的需要。 @Martin 对不起,它应该不为空,我已经更正了我的答案。 不知道为什么我认为 WITH VALUES 是必要的,今天刚刚在另一个项目中遇到了同样的情况,并认为我会再次尝试您的解决方案:不需要 WITH VALUES。 MSDN 也确认:“如果新列不允许空值,则无论是否指定 WITH VALUES,都将默认值存储在新行中。” - msdn.microsoft.com/en-us/library/ms187742.aspx 不知道你为什么用“答案没有添加任何新信息,接受的答案涵盖所有内容”来标记自己的答案。

以上是关于如何在 SQL Server 的单个批次中为列添加默认值并使用默认值更新所有行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 中将行动态转换为列

如何在 vb.net、SQL Server 中为多个搜索制作代码

如何在 SQL Server 或 C# 代码中将行转换为列

如何在透视中为列提供自定义名称

表中行上的 SQL Server Datediff

SQL Server:如何在查询分析器中中止一系列批处理?