在为变量设置值时处理NULL值

时间:2015-12-03 07:52:56

标签: sql sql-server tsql

我已尝试过以下查询,以检查当前年份是否为闰年。

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()
                       )

如果表中不存在给定日期的数据,则第一个查询将@leapyearstrt作为0返回,但第二个查询将@leapyearstrt作为NULL返回。

为什么会这样?如果表中不存在数据,如何在0语句中分配SET值?

(P.S:我使用SET来分配值,因为select可能会返回多行)

2 个答案:

答案 0 :(得分:1)

首先,如果SELECT返回超过1行,则SET(您的第二个查询)将失败:

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,<,< =,>,> =或当子查询用作   表达。

但是,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);

答案 1 :(得分:0)

您可以使用ISNULL函数,假设子查询返回一行:

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

这两者之间的区别在于,在第一个查询中,如果未找到行,则根本不执行赋值。在第二个版本中,它被执行,是否找到了行。