我有一个列Column
,它被声明为NULL DEFAULT(GETUTCDATE())
,并且有一个包含该列的非聚集索引。我想把这个列改为NOT NULL DEFAULT(GETUTCDATE())
,当我运行ALTER TABLE ALTER COLUMN
语句时,SQL Azure服务说它不能改变这个列,因为有一个索引依赖于这个列。
这是一个生产数据库,该表包含大约1000万条记录。因此,我宁愿不删除并重新创建索引,因为这会降低数据库的速度(特别是创建索引可能需要几分钟)。
如何在不重新创建索引的情况下更改列?
不需要修改表列来强制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