SQL Server 将系统版本化列可为空的列更改为非空

r3i60tvu  于 2022-11-21  发布在  其他
关注(0)|答案(3)|浏览(174)

我使用的是SQL Server和系统版本(临时)表。在我的主表中,有一个INT列当前允许空值。我想将其更新为不允许空值,但该表的系统/历史副本允许空值。
我运行以下语句:

ALTER TABLE dbo.MyTable 
    ALTER COLUMN MyInt INT NOT NULL;

我得到这个错误:
无法将值NULL插入到表“mydb.dbo.MyTable_History”的列“MyInt '。该列不允许空值UPDATE失败
我使用以下脚本创建了系统版本化表:

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

在这种情况下,是否有其他方法可以使主表的列不可为空?我想我可以(也许)用任意垃圾值手动更新现有的系统版本化空值,但似乎时态表应该支持这种情况。

oogrdqng

oogrdqng1#

我也看了一下,似乎必须将系统版本列中的NULL值更新为某个值。

ALTER TABLE dbo.MyTable
    SET (SYSTEM_VERSIONING = OFF)
GO
UPDATE dbo.MyTable_History
    SET MyInt = 0 WHERE MyInt IS NULL --Update to default value
UPDATE dbo.MyTable
    SET MyInt = 0 WHERE MyInt IS NULL --Update to default value
ALTER TABLE dbo.MyTable
    ALTER COLUMN MyInt INT NOT NULL
ALTER TABLE dbo.MyTable_History
    ALTER COLUMN MyInt INT NOT NULL
GO
ALTER TABLE dbo.MyTable 
    SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.MyTable_History));
GO
qrjkbowd

qrjkbowd2#

我在尝试添加新的非空列时遇到了这个问题。我最初尝试将该列创建为可空,更新所有值,然后将其设置为不可空:

ALTER TABLE dbo.MyTable 
    ADD COLUMN MyInt INT NULL;

GO

UPDATE dbo.MyTable
    SET MyInt = 0;

GO

ALTER TABLE dbo.MyTable 
    ALTER COLUMN MyInt INT NOT NULL;

但我设法通过使用一个临时的默认约束来解决这个问题:

ALTER TABLE dbo.MyTable 
    ADD COLUMN MyInt INT NOT NULL CONSTRAINT DF_MyTable_MyInt DEFAULT 0;

ALTER TABLE dbo.MyTable
    DROP CONSTRAINT DF_MyTable_MyInt;
knsnq2tg

knsnq2tg3#

虽然您可以更改临时表的模式,但当表是系统版本时,某些操作不能通过直接ALTER执行。其中之一是将可空列更改为NOT NULL。
请参阅重要说明-更改系统版本化时态表的方案
在这种情况下,您唯一可以做的就是使用以下命令关闭系统版本控制:

ALTER TABLE schema.TableName SET (SYSTEM_VERSIONING = OFF);

这样就剩下两个单独的表-表本身和它的历史记录表都是单独的对象。现在可以对这两个表进行模式更新(它们必须是模式对齐的),然后可以重新打开系统版本控制:

ALTER TABLE schema.TableName SET (SYSTEM_VERSIONING = ON);

相关问题