2015-12-03 47 views
1

我有以下代碼:爲什麼Select語句如果不返回結果則不會分配空字符串或空值?

declare @testValue nvarchar(50) = 'TEST'; 

select @testValue = 'NOTUSED' where 1 > 2; 
select @testValue; -- Outputs 'TEST' 
select @testValue = 'USED' where 2 > 1; 
select @testValue; -- Outputs 'USED' 

通過以上,是從未使用過的第一項任務,因爲在where子句失敗。第二個是正確完成並使用返回。

爲什麼SQL在這種情況下不返回空值,並且在where子句失敗的第一個賦值之後將NULL值賦給@testValue?

+0

那些>標誌是否正確? 2> 1是真的,對嗎? – mikey

+0

也值看起來應該是testValue – swestner

+0

嗯。你是對的。我得到它倒退。運行時的第一個選擇語句將返回一個空的結果集。但是在這種情況下,@testValue永遠不會設置爲NULL或空字符串。它仍然保留了'TEST'的價值。我很好奇爲什麼會發生這種情況,如果我錯過了一些東西。 – SamIAm

回答

2

這是預期的行爲:

「如果SELECT語句返回任何行,可變保持其當前值。如果表達式是一個標量子查詢不返回值,該變量被設置爲NULL。」

https://msdn.microsoft.com/en-us/library/ms187330.aspx

您可以在右側使用子查詢解決這個問題在你的榜樣。

SELECT @testValue = (SELECT 'NOTUSED' where 1 > 2); 

至於爲什麼是這樣,我不能肯定地說。也許整個@testValue = 'NOTUSED'等於NULL,而不是僅僅聲明的右邊'NOTUSED'部分,並且這可以防止設置參數。不直接相關,但我可以說,當涉及到NULL時,我花了一些時間來增加對編寫查詢的信心。您需要了解/熟悉ANSI NULL規範和相關行爲。

+0

如果您將其設置爲SET @testValue =(SELECT ...),這可能會更清晰。 – ErikE

+0

理解並同意,但我確實希望證明子查詢本身足以達到預期的效果,因爲這可能會提供一些有關爲什麼發動機的行爲方式的見解。 – mikey

+0

我認爲SET確實如此。全部是關於行集和值(和表達式)之間的區別。 SELECT用於行集。在分配變量的查詢中,沒有行意味着沒有分配。但是,如果SELECT重載以分配*值*,那麼「無行AS值」爲NULL。這是使用魔法的圓括號。嘗試使用兩列括號或使用返回多於一行的查詢... – ErikE

0

這是SELECT的默認行爲。

當使用SELECT爲變量賦值時,如果沒有返回值,SELECT將根本不會進行賦值,因此變量值不會被更改。

另一方面,如果沒有返回值,SET將爲該變量分配NULL

For more info

0

NULL是你想的理想值,但SQL引擎是不是足夠聰明,因爲一些別的可能要空字符串「」在這種情況下0或1,你看。所以沒有設置單個默認值。 Best設置您自己的默認值。您可以在下面看到

DECLARE @testValue NVARCHAR(50) = 'TEST'; 

SELECT @testValue = 'NOTUSED' WHERE 2 > 1; 

IF 2 <> 1 
    SELECT @testValue = NULL; 

SELECT @testValue; -- Outputs 'TEST' 
SELECT @testValue = 'USED' WHERE 1 > 2; 
SELECT @testValue; -- Outputs 'USED' 
0

NULL SQL中用於表示缺失數據或未知值。在這種情況下,數據不會丟失,@testValue的值是已知的,它只是失敗了一個賦值條件,所以它沒有新的值。

如果你要改變你的初始分配是這樣

declare @testValue nvarchar(50) 

你會得到NULL象下面這樣:

select @testValue = 'NOTUSED' where 1 > 2; 
select @testValue; -- Outputs NULL 
select @testValue = 'USED' where 2 > 1; 
select @testValue; -- Outputs 'USED' 

不要太失望,你不是在越來越NULL回你的榜樣。 NULL不容易處理。

例如,您無法比較兩個NULL值,因爲NULL的實例不相等。因此,您還需要使用ISNULL等特殊運算符來檢查它。

一般而言,NULL作爲編程構造應該避免在我看來。這在編程語言中有點爭議。但是,即使是創建者null,也要求這個「十億美元的錯誤」創建爲null。

相關問題