2015-11-30 41 views
3

假設我有兩個可能爲NULL的變量,我想檢查它們是否不同。在T-SQL中比較兩個可用NULL的變量

,我想:

  • 處理兩個空值作爲平等的(而不是NULL)。
  • 將NULL和非NULL視爲不相等(不爲NULL)。

我知道我可以只寫:

DECLARE @v1 int = ...; 
DECLARE @v2 int = ...; 

IF (
    (@v1 IS NULL AND @v2 IS NOT NULL) 
    OR (@v1 IS NOT NULL AND @v2 IS NULL) 
    OR @v1 <> @v2 
) 
    PRINT 'Different!'; 

但有一個更優雅的方式?

+1

可以簡化這個條件否定它:'NOT(@ V1 IS NULL和@ V2爲空或@ V1 = V2 @) –

+0

@MarkShevchenko認爲這NULL和0是相等的。 –

+0

嗯,愛這種棘手的問題! –

回答

1

還有一個選項,但我不確定它是否會更優雅。

IF NOT(NULLIF(@v1, @v2) IS NULL AND NULLIF(@v2, @v1) IS NULL) 
PRINT 'Different!'; 
+0

迄今爲止最好的答案,在我看來。表現也不錯(等於「我的」IF)。謝謝! –

+0

很高興聽到它!如果NULLIF函數更聰明一點(現在:如果第一個值爲NULL,然後fuction返回NULL,但我建議微軟的開發人員檢索秒值而不是NULL),那麼我們將有更短,更優雅的解決方案;) –

0

嘗試這樣:

DECLARE @v1 INT = ...; 
DECLARE @v2 INT = ...; 

IF ISNULL(@v1, -1) <> ISNULL(@v2, -1) 
    PRINT 'Different!' 
+1

這認爲NULL和-1是相等的。 –

+0

@BrankoDimitrijevic - 它確實,但是你真的需要支持'int'範圍內的所有值嗎?通常,您可以找到某種不應存在於實際數據中的哨點值並使用它。 –

+1

@Damien_The_Unbeliever是的,除非/直到數據庫被設計和實施以保護自己免受此類損失。這比製作更短一點的IF值得更麻煩。 –

0
DECLARE @v1 INT = NULL 
DECLARE @v2 INT = 1 

IF CHECKSUM(@v1) != CHECKSUM(@v2) 
    PRINT 'Different!' 
+2

這認爲NULL和2147483647是平等的。 –

5

爲了表明有很多方法可以做到這一點。

IF EXISTS(SELECT @v1 EXCEPT SELECT @v2) 
    PRINT 'Different' 
+3

行爲正確,但比我的「普通」IF(比如在大多數情況下可能不是問題)要慢大約2倍,並且更難以閱讀(恕我直言),所以我不會接受它作爲答案。不過謝謝你的努力! +1 –

0

,無需瞭解更廣泛的方案,其中該代碼將被用於任何東西,我們經常使用的空當量值,這是一個值,它是有效的數據類型,但該方案的有效範圍之外。例如,如果你的程序只使用正整數,使用空等效值-1將意味着可能有如下情況:

IF ISNULL(@v1, -1) != ISNULL(@v2, -1) -- or COALESCE if you prefer 
    PRINT 'Different!'; 

如果整數值的全範圍是有效條目,那麼它是不是可能使用null-equivalent值。如果是這樣的話,你的原始方法絕對沒有錯。

我會建議任何人不要對這樣的事情太聰明,以後會讓你痛苦。把事情簡單化!

0

多一個選擇是:

SET ANSI_NULLS OFF 
IF @v1 != @v2 
    PRINT 'Different!'; 
SET ANSI_NULLS ON 
+2

謝謝,但' SET ANSI_NULLS OFF'已棄用。從MSDN引用:「在將來的SQL Server版本中,ANSI_NULLS將始終爲ON,任何明確將該選項設置爲OFF的應用程序都會產生錯誤。避免在新開發工作中使用此功能,並計劃修改當前使用此功能。「_。 –

+0

是的,但在2012年和更早版本中,此方法應該正常工作。任何方式,答案已經發布只是爲了獲得信息,這個任務可以使用這個解決方案來執行。而且,您還沒有指定您在使用SQL Server版本時有一些限制。 – Vasily

+0

使用不推薦使用的功能很少是一個好主意,即使它們仍然可用。特別是如果你計劃你的軟件有很長的壽命...... –