当我使用下面的测试脚本创建检查约束时,仍然允许违反约束的数据进入表,并且约束仍然显示为受信任。
我意识到检查约束没有正确检查 NULL(它包括column = null
而不是column IS null
),但我仍然希望 SQL Server 不允许“ASDF”、“3”或 NULL 值,因为检查条件评估为 false反对这些价值观。有人可以解释为什么这个检查约束允许以下值:NULL、'3'、'ASDF'?
如果我将约束条件更改为(checkMe is null or checkMe = '1' or checkMe = '2')
,则它按预期工作。
SQL Server 版本:Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64)
CREATE TABLE dbo.testCheck(checkMe varchar(50));
go
向表中插入数据
INSERT INTO dbo.testCheck(checkMe)
VALUES ('1'),('2'),(NULL),('3');
GO
添加约束,检查以便检查现有数据。我希望 NULL 和 '3' 都违反了这个检查,但它以某种方式成功了。
ALTER TABLE dbo.testCheck WITH CHECK
ADD CONSTRAINT ck_testCheck
CHECK (checkMe = null or checkMe = '1' or checkMe = '2');
GO
添加检查约束后尝试插入无效数据...成功了吗?
INSERT INTO dbo.testCheck(checkMe) VALUES('ASDF');
GO
显示表包含无效数据,并且此约束被标记为受信任,这意味着表中的所有数据都已针对约束进行了验证
SELECT *
--this is the same logic as in the check constraint, shows 3 rows that do not pass
, checkConstraintLogic = case when (checkMe = null or checkMe = '1' or checkMe = '2') then 'PASS' else 'FAIL' end
FROM dbo.testCheck;
go
SELECT parentObject = isnull(OBJECT_SCHEMA_NAME(k.parent_object_id) + '.', '') + OBJECT_NAME(k.parent_object_id)
, k.name, k.is_not_trusted
FROM sys.check_constraints k
WHERE k.parent_object_id = object_id('dbo.testCheck')
ORDER BY 1;
GO
脚本输出: