2014-02-05 45 views
1

我有这样的检查约束,逻辑XOR和NULL检查

CONSTRAINT [CK_VerboseXNOR] CHECK 
    (([A] IS NULL AND [B] IS NULL) OR ([A] IS NOT NULL AND [B] IS NOT NULL)) 

它断言,要么AB都是NULL,或者两者都不NULL。您可能会考虑使用XNOR操作。

是否有一个更简洁的方式来写在TSQL,避免每个术语的双重用途。


理想情况下,我想这(你不能阻止我在做梦。)

CONSTRAINT [CK_SuccinctXNOR] CHECK ([A] IS NULL XNOR [B] IS NULL) 

编辑

我已经试过

CHECK (CASE WHEN [A] IS NULL THEN [B] IS NULL ELSE [B] IS NOT NULL END) 

看起来像只有三个评估,但它没有工作(不会解析)。

我还没有试过

CHECK (IIF([A] IS NULL, [B] IS NULL, [B] IS NOT NULL)) 

,并给出了上述的故障,我不够乐观的尝试。

我不能完全理解CHECK如何接受逻辑表达式,但CASE(和pegps IIF)不能返回一个。

回答

3

XNOR就是平等的。 XOR不等于。

因为在T-SQL没有布尔类型(没有很好的理由),我们有滥用整数:

WHERE 
(CASE WHEN [A] IS NULL THEN 1 ELSE 0 END) 
= (CASE WHEN [B] IS NULL THEN 1 ELSE 0 END) 

不漂亮无论是。

马丁的变种稍微好一点的是:

WHERE IIF(A IS NULL, 0, 1) = IIF(B IS NULL, 0, 1) 

我通常使用已写在你的问题的形式。优化器识别此表单(例如,对于索引查找),但它不识别基于整数的表单。

+1

稍微更简洁的变体是'DECLARE @T表(A INT,B INT,CHECK(IIF(A IS NULL,0,1) = IIF(B IS NULL,0,1)))' –

+0

@MartinSmith,usr,我对这个问题增加了内容。欢迎收到任何进一步的信息。 – Jodrell

+0

@Jodrell你试图使用布尔表达式作为布尔类型的值。 T-SQL没有布尔类型。 '0 = 0'没有类型。您只能在T-SQL语法明确指出的地方使用它。 (是的,这不是有用的行为。) – usr

0

如何编写一个函数来执行XNOR并在约束中调用它?

我从来没有下这个自己,但谷歌弹出:Check Constraints That Call Functions

+0

我可以但是我担心我打字时会省下什么,我会失去表现。 – Jodrell

+0

敢不敢提'p'字?正如'profile'中。我不知道使用函数是好事还是坏事。 –