将新的NOT NULL列添加到现有数据库

时间:2018-01-31 09:27:26

标签: sql database-design sql-server-2016

假设我有一个有人员表的系统:

CREATE TABLE Person
(
    FirstName NVARCHAR(50) NOT NULL,
    LastName  NVARCHAR(50) NOT NULL,
    DOB       DATE NOT NULL
)

如果我们想要在系统运行多年后对系统进行更新,我们现在想要捕获该人的地址(通过名为Address的新的NVARCHAR列{{1} }})

因此,我们希望所有新记录都为NOT NULL,但我们没有旧记录的任何数据,因此它们必须为NULL

最好的方法是什么?我们无法添加NOT NULL列,因为它对所有现有记录都是NULL。

添加列并允许NULLS的最佳方法是,在现有记录中添加一些占位符值(EG'。'),然后将列更改为NULL?

还是有其他方法可以做到吗?

1 个答案:

答案 0 :(得分:2)

如果没有为现有行分配非NULL值(通过默认约束),则无法添加新的NOT NULL列。但是,您可以添加NULL列,并通过指定禁止NOT NULL值和NULL选项的检查约束来确保只有NOCKECK值,以便现有数据为未经验证:

CREATE TABLE dbo.Person
(
    FirstName NVARCHAR(50) NOT NULL,
    LastName  NVARCHAR(50) NOT NULL,
    DOB       DATE NOT NULL
)
INSERT INTO dbo.Person (FirstName, LastName , DOB)
    VALUES(N'foo', N'bar', '20010101');
GO
--add new column and CHECK constraint with NOCHECK
ALTER TABLE dbo.Person WITH NOCHECK
    ADD Address nvarchar(50) NULL
    CONSTRAINT CK_Person_Address CHECK (Address IS NOT NULL);
GO
--this fails due to check constraint violation
INSERT INTO dbo.Person (FirstName, LastName , DOB)
    VALUES(N'foo2', N'bar2', '20020101');
GO
--this succeeds
INSERT INTO dbo.Person (FirstName, LastName , DOB, Address)
    VALUES(N'foo2', N'bar2', '20020101', N'non-null address');
GO

此方法为现有人员提供了正确的NULL语义,这些人员没有地址,但保证新人的数据完整性。