当索引依赖于该列而不重新创建索引时,如何将列从 null 更改为非 null?

Posted

技术标签:

【中文标题】当索引依赖于该列而不重新创建索引时,如何将列从 null 更改为非 null?【英文标题】:How do I change a column from null to not null when an index depends on that column without recreating the index? 【发布时间】:2014-10-19 16:04:40 【问题描述】:

我有一列 Column 被声明为 NULL DEFAULT(GETUTCDATE()) 并且有一个包含此列的非聚集索引。我想将此列更改为NOT NULL DEFAULT(GETUTCDATE()),当我运行ALTER TABLE ALTER COLUMN 语句时,SQL Azure 服务说它无法更改该列,因为有一个取决于该列的索引。

这是一个生产数据库,该表包含大约一千万条记录。所以我宁愿不删除并重新创建索引,因为这会减慢数据库的速度(尤其是创建索引可能需要几分钟)。

如何在不重新创建索引的情况下更改列?

【问题讨论】:

相关:***.com/questions/1258380/… 我已经在本地服务器(即不是 Azure)上的 SQL Server 2012 SP1 上对此进行了测试,但它也不起作用。因此很可能有必要删除索引并在 Azure 上重新创建它。 ALTER TABLE Children ALTER COLUMN ChildName VARCHAR(50) NOT NULL 产生:Msg 5074,Level 16,State 1,Line 1 索引“IX_Children_ChildName”取决于列“ChildName”。消息 4922,级别 16,状态 9,第 1 行 ALTER TABLE ALTER COLUMN ChildName 失败,因为一个或多个对象访问此列。 (当然,无论如何都要检查列中是否没有NULL,这将是一个错误ev 【参考方案1】:

不必更改表列以强制执行 NOT NULL。相反,可以将新约束添加到表中:

ALTER TABLE [Table] WITH CHECK
   ADD CONSTRAINT [TableColumnNotNull] CHECK ([Column] Is NOT NULL);

这不会影响索引,但优化器会使用此约束来提高性能:

CREATE TABLE Test (ID bigint PRIMARY KEY, [Column] DATE NULL DEFAULT(GETUTCDATE()));
GO --< Create test table

CREATE NONCLUSTERED INDEX TestColumnIdx ON Test ([Column]);
GO --< Create the index

ALTER TABLE Test ALTER COLUMN [Column] DATE NOT NULL;
GO --< That won't work: the index 'TestColumnIdx' is dependent on column 'Column'

Select * From Test Where [Column] Is NULL;
GO --< Check the plan: it has "Index Seek (NonClustered)"

ALTER TABLE Test WITH CHECK ADD CONSTRAINT TestColumnNotNull CHECK ([Column] Is NOT NULL);
GO --< Add a "stand-alone" NOT NULL constraint

Select * From Test Where [Column] Is NULL;
GO --< Check the plan: it has "Constant Scan" now

DROP TABLE Test;
GO --< Clean-up

【讨论】:

赞成,因为它提供了一个具有问题设置的约束的解决方案,但对于长期可支持性而言,理想情况下,该列似乎会在某个时间点发生变化,而它所花费的时间不会影响用户。

以上是关于当索引依赖于该列而不重新创建索引时,如何将列从 null 更改为非 null?的主要内容,如果未能解决你的问题,请参考以下文章

如何重命名 df 列而不将列列表临时存储到变量中?

将列从日期转换为日期时间

包含使用列而不是文本值或变量的全文索引

是否可以只更新 pypi 索引中的详细信息,而不重新创建包?

如何在 JQuery 中添加和删除数组而不重新索引数组键

如何定义游标,当我们在两个表之间有一个公共列而不给出别名时