2015-12-03 62 views
0

我已經嘗試了下面的查詢來檢查當前年份是否爲閏年。在設置變量值時處理NULL值

Declare @leapyearstrt int = 0 

--1st query 
select @leapyearstrt = ISNULL(ISLEAPYEAR,0) 
         FROM [dbo].[TimeElement] 
         WHERE CurrentDate = getdate() 

--2nd query 
SET @leapyearstrt = (SELECT isnull(ISLEAPYEAR,0) 
         FROM [dbo].[TimeElement] 
         WHERE CurrentDate = getdate() 
         ) 

如果數據不存在於表中給定日期,第一次查詢返回@leapyearstrt0,但第二個查詢返回@leapyearstrt作爲NULL

爲什麼發生?如果數據在表中不存在,如何在SET語句中分配0值?

(PS:我已經使用SET分配,因爲select可能返回多行的值)

+0

沒有記錄沒有價值 – lad2025

+0

如果沒有值,則參數必須返回默認值分配給它。是嗎? – bmsqldev

+0

[SET與SELECT分配變量時可能出現重複?](http://stackoverflow.com/questions/3945361/set-versus-select-when-assigning-variables) – lad2025

回答

1

首先,如果SELECT回報超過1行,然後SET(你的第二個查詢)失敗:

子查詢返回多個值。當 子查詢遵循=,!=,<,< =,>,> =或當子查詢用作 表達式時,這是不允許的。

但是,SELECT(您的第一個查詢)中的變量賦值有效。雖然沒有定義哪個行將用於分配最終值。


如果你想使用SET,然後確保SELECT回報至多1行:

SET @leapyearstrt = (SELECT TOP(1) isnull(ISLEAPYEAR,0) 
         FROM [dbo].[TimeElement] 
         WHERE CurrentDate = getdate() 
     -- ideally you should add a proper ORDER BY to pick the row that you need 
         ); 

,然後添加這行代碼覆蓋的情況下SELECT返回0行。

SET @leapyearstrt = ISNULL(@leapyearstrt, 0); 
0

可以使用ISNULL功能,假設子查詢返回一行:

SET @leapyearend = ISNULL((SELECT TOP 1 ISLEAPYEAR 
          FROM [dbo].[TimeElement] 
          WHERE CurrentDate = getdate() 
          ), 0) 

的這兩者之間的區別在於,在第一個查詢中,如果未找到行,則根本不會執行分配。在第二個版本中,它被執行了。

+2

如果子查詢返回多於一行? – lad2025

+0

@ lad2025,正確的評論,補充更正,但從表和列的名字,我想它不應該返回多一行。 –

+1

OP說:'P.S:我用SET來分配值,因爲select可能返回多於一行' – lad2025