检查约束不会在SQL Server 2016
问题描述:
工作,我有以下检查约束不会在SQL Server 2016
begin tran
CREATE TABLE [dbo].[Filters]
(
[Id] INT NOT NULL IDENTITY,
[FCode] varchar(30) null,
[FVersion] varbinary(892) null,
CONSTRAINT [PK_Filter] PRIMARY KEY CLUSTERED ([Id]),
CONSTRAINT [CK_Filters_FCode_FVersion]
CHECK (([FCode] IS NULL AND [FVersion] IS NULL)
OR (LEN([FCode]) > 0 AND DATALENGTH([FVersion]) > 0)),
)
INSERT INTO [dbo].[Filters] (FCode, FVersion)
VALUES (NULL, NULL),
(NULL, 0x6BE348),
('ASD', NULL),
('ASD', 0x6BE348)
SELECT
IIF(([FCode] IS NULL AND [FVersion] IS NULL)
OR (LEN([FCode]) > 0 AND DATALENGTH([FVersion]) > 0) , 1, 0) AS [check], *
FROM
[dbo].[filters]
rollback
我想到的是,第二和第三插入语句会导致违反约束一个简单的例子。但是服务器允许它们。
使用select语句查看第2行和第3行违反约束检查的值。查看结果
check Id FCode FVersion
------------------------------
1 1 NULL NULL
0 2 NULL 0x6BE348
0 3 ASD NULL
1 4 ASD 0x6BE348
任何想法?
答
检查约束条件只有当值为最终值时才会失败false
。
您希望违反约束条件的表达式评估为UNKNOWN
。
您可以
它返回
+---------+----------+--------------------+----+-------+----------+
| check | LenFCode | DataLengthFVersion | Id | FCode | FVersion |
+---------+----------+--------------------+----+-------+----------+
| True | NULL | NULL | 1 | NULL | NULL |
| Unknown | NULL | 3 | 2 | NULL | 0x6BE348 |
| Unknown | 3 | NULL | 3 | ASD | NULL |
| True | 3 | 3 | 4 | ASD | 0x6BE348 |
+---------+----------+--------------------+----+-------+----------+
之所以看到这一点,他们是UNKNOWN
是因为LEN
和DATALENGTH
都在传递NULL
答
Martin Smith的答案已经返回NULL
包括为什么SQL服务器被允许的原因在不违反检查约束的情况下指定值。
您可以修改您的检查约束以使其工作。 Demo
CONSTRAINT [CK_Filters_FCode_FVersion]
CHECK (([FCode] IS NULL AND [FVersion] IS NULL)
OR (LEN(ISNULL([FCode],'')) > 0
AND ISNULL(DATALENGTH([FVersion]),-1) > 0))
谢谢!这是原因。 –
极好的例子 – TheGameiswar