2014-02-05 80 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'中。我不知道使用函數是好事還是壞事。 –