SQL Server | IsNull | DateTime和SmallDateTime

时间:2016-09-06 22:13:51

标签: sql-server datetime

我有下表:

create table #temp_1234
(
    field1 varchar(50) null,
    field2 datetime null,
    field3 smalldatetime null
)

然后,我在其中插入以下行:

insert into #temp_1234
(field1, field2, field3)
values ('Val1','2016-09-16 23:59:59.000',NULL)

如果我执行查询

select field2 from #temp_1234

我得到的结果是' 2016-09-16 23:59:59.000 '。

但是当我执行查询时

select ISNULL(field3,field2)  from #temp_1234

结果变为' 2016-09-17 00:00:00 '。

即使在两个查询中都返回相同的列,但两种情况下的结果是不同的呢?

我理解' smalldatetime '精确到一分钟,' 日期时间'精确到一秒钟。但是,如何引入空检查会改变返回结果的精度?

3 个答案:

答案 0 :(得分:3)

ISNULL使用两个参数check_expressionreplacement_value。正如replacement_value的文档中所述:

如果check_expression为NULL,则返回表达式。 replacement_value必须是可以隐式转换为check_expresssion类型的类型。

实质上,SQL Query引擎隐式转换值以进行比较。 Datetime的准确度为3.33ms,因此最有可能考虑舍入。

如果您希望更好地控制转化,请考虑使用CAST,例如CONVERTISNULL

这也可能是explicit conversions函数的一个很好的用例,而不是JTree

答案 1 :(得分:0)

isnull将第二个值转换为第一个值格式。

这更清楚:

声明@date日期,@ datetime datetime = getdate() select isnull(@date,@ datetime)

答案 2 :(得分:0)

select ISNULL(field3,field2)  from #temp_1234

当您对上述查询进行检验时,“field2”的值将转换为smalldatetime类型,因为field3的数据类型为smalldatetime。这就是ISNULL返回不同值的原因。要验证您是否可以运行以下查询:

select cast(field2 as smalldatetime) from #temp_1234

smalldatetime中,秒部分始终为零(00)。如果datetime值的秒大于或等于30,则将1分钟添加到结果smalldatetime值,并将秒设置为零。对于小于30的秒,结果smalldatetime值将秒部分设置为00,将分段设置为与之前相同。

在您的情况下,datetime值为:'2016-09-16 23:59:59.000'。由于datetime值的秒部分大于30,因此将1分钟添加到生成的smalldatetime值中,该值给出值:'2016-09-17 00:00:00'。