Sql server SQL Server | IsNull | DateTime和SmallDateTime

Sql server SQL Server | IsNull | DateTime和SmallDateTime,sql-server,datetime,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 fie

我有下表:

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”精确到一分钟,“datetime”精确到一秒钟。但是引入空检查如何改变返回结果的精度呢?

使用了两个参数,
check\u表达式
replacement\u值
。如
替换值文件中所述:

如果check_表达式为NULL,则返回的表达式。替换值必须是可隐式转换为check\u expression类型的类型

本质上,SQL查询引擎是隐式转换值以进行比较
Datetime
的精度为,因此很可能是四舍五入的原因

如果您想对转换进行更多的控制,请考虑使用诸如<代码> CAST 或<代码>转换< /代码> .< 这可能也是函数的一个很好的用例,而不是

ISNULL

使用两个参数,即
check\u表达式
替换值
。如
替换值文件中所述:

如果check_表达式为NULL,则返回的表达式。替换值必须是可隐式转换为check\u expression类型的类型

本质上,SQL查询引擎是隐式转换值以进行比较
Datetime
的精度为,因此很可能是四舍五入的原因

如果您想对转换进行更多的控制,请考虑使用诸如<代码> CAST 或<代码>转换< /代码> .<


这可能也是函数的一个很好的用例,而不是将第二个值强制转换为第一个值格式

这一点更加明确:

声明@date-date,@datetime-datetime=getdate()
选择isnull(@date,@datetime)

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

这一点更加明确:

声明@date-date,@datetime-datetime=getdate() 选择isnull(@date,@datetime)

执行上述查询时,“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,因此在生成的
smalldatetime
值中添加了1分钟,该值给出了值:“2016-09-17 00:00:00”

执行上述查询时,“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值的seconds部分大于30,因此在生成的
smalldatetime
值中添加1分钟,该值给出值:“2016-09-17 00:00:00”。

isnull强制第一个输入的数据类型(或者更确切地说,将第二个转换为第一个)。e、 g.
DECLARE@var1 VARCHAR(5);声明@var2 VARCHAR(10)='asdfghjkl;';选择ISNULL(@var1,@var2)将生成“asdfg”。。。因此,您强制field2成为isnull中的smalldatetime。isnull强制第一个输入的数据类型(或者更确切地说,将第二个转换为第一个)。e、 g.
DECLARE@var1 VARCHAR(5);声明@var2 VARCHAR(10)='asdfghjkl;';选择ISNULL(@var1,@var2)将生成“asdfg”。。。因此,您正在强制field2成为isnull中的smalldatetime。