I'm using SQL Server and system-versioned (temporal) tables. In my main table, I have an INT
column that's currently allowing NULLs. I want to update this to not allow nulls, but the system/history copy of the table allows nulls.
I run this statement:
ALTER TABLE dbo.MyTable
ALTER COLUMN MyInt INT NOT NULL;
And I get this error:
Cannot insert the value NULL into column 'MyInt', table 'mydb.dbo.MyTable_History'; column does not allow nulls. UPDATE fails.
I had created the system versioned table using this script:
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
Is there some other way I can make my main table's column non-nullable in this scenario? I suppose I could (maybe) manually update the existing system-versioned null values with an arbitrary garbage value, but it seems like this scenario should be supported with temporal tables.
ALTER TABLE ... WITH NOCHECK ADD CONSTRAINT CK_MyInt_NotNull CHECK (MyInt IS NOT NULL)
to add the constraint for new rows after the fact without checking existing rows. (Disclaimer: not tested.) This is a little iffy since it's not literally the same thing as marking a columnNOT NULL
and it will break on reimporting data, but then that's also exactly why your scenario fails: versioned tables version data, but not the structure. Any successful structure changes are propagated to the history table instead, which, even when it works, is not exactly faithful to history. – Quincuncial