我正在使用 SQL Server 和系统版本化(时间轴)表。在我的主表中,我有一个允许 NULL 值的 INT
列。我希望将其更新为不允许 NULL 值,但是系统/历史拷贝的表允许 NULL 值。
我运行以下语句:
ALTER TABLE dbo.MyTable
ALTER COLUMN MyInt INT NOT NULL;
我遇到了以下错误:
无法将空值插入到“mydb.dbo.MyTable_History”表的“MyInt”列中;该列不允许空值。更新失败。
我使用以下脚本创建了系统版本控制表:
ALTER TABLE dbo.MyTable
ADD
ValidFrom DATETIME2 (2) GENERATED ALWAYS AS ROW START HIDDEN CONSTRAINT DFMyTable_ValidFrom DEFAULT DATEADD(SECOND, -1, SYSUTCDATETIME()),
ValidTo DATETIME2 (2) GENERATED ALWAYS AS ROW END HIDDEN CONSTRAINT DFMyTable_ValidTo DEFAULT '9999.12.31 23:59:59.99',
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo);
ALTER TABLE dbo.MyTable
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.MyTable_History));
GO
在这种情况下,我是否有其他方法可以使我的主表列成为非空列?我想我可以手动使用任意垃圾值更新现有的系统版本空值,但是似乎应该支持使用时间表解决此场景。
ALTER TABLE ... WITH NOCHECK ADD CONSTRAINT CK_MyInt_NotNull CHECK (MyInt IS NOT NULL)
来添加约束条件,以便在事后为新行添加约束条件而无需检查现有行。(免责声明:未经测试。)这有点棘手,因为它并不是字面上将列标记为NOT NULL
,并且在重新导入数据时会出现问题,但这也正是您的情况失败的原因:版本化表对数据进行版本控制,但不对结构进行版本控制。任何成功的结构更改都会传播到历史表中,即使它起作用,也不完全忠实于历史记录。 - Jeroen Mostert