假设我有下表:
CREATE TABLE test(test_id int not null identity primary key,
field1 int not null,
field2 int
);
CREATE INDEX IDX_test_field1 ON test(field1);
CREATE INDEX IDX_test_field2 ON test(field2);
现在ALTER TABLE test ALTER COLUMN field1 int
工作,并field1
允许null
.
然而,我无法改变ALTER TABLE test ALTER COLUMN field2 int not null
,因为
ALTER TABLE ALTER COLUMN field2 失败,因为一个或多个对象访问此列。
另外,我无法更改field1
回not null
.
但是,我可以根据需要多次添加然后删除检查约束:
ALTER TABLE test ADD CONSTRAINT CHK_NN_field2 CHECK (field2 IS NOT NULL);
DROP CONSTRAINT CHK_NN_field2` without any problems.
它是明确定义的行为吗?有人可以解释为什么会发生这种情况或指向我的文档吗?
如果这很重要,我正在使用 SQL Server 2008 R2。
谢谢你。
相关文档在这里
在实践中,似乎 SQL Server 确实允许一些超出文档中提到的其他情况。
正如您在问题中显示的
ALTER TABLE test ALTER COLUMN field1 int null
那样,实际上确实有效,因此对索引中使用的列的更改限制似乎与用户创建的统计信息的限制相同。此外,关于主键的警告似乎也不真实。以下工作正常。
您在 field1 和 field2 上的索引阻止您将列从 NULL 更改为 NOT NULL。删除索引,将其更改为 NOT NULL,然后重新创建索引。
NULL
是比 更宽松的限制NOT NULL
。NULL
如果您尝试更改为NOT NULL
(违反约束并失败)时有字段,而当您有字段时,会发生什么情况NOT NULL
,更改为NULL
(无影响)。当您创建约束时,必须在表更改之前验证数据以符合该约束(否则它会失败) - 据我观察,这种行为不会发生在 alter 或 drop 上,而是以这种方式更改约束被简单地阻止了。