Cast和Convert在SQL Server中的区别

3

我经常处理SQL Server中的日期时间列。现在大部分时间我需要将日期时间的时间部分重置为'00:00:00.000'。

我使用cast函数来实现相同的效果:

select cast(cast(getdate() as date)as datetime)

现在我的团队中有些成员使用其他函数:
select cast(floor(cast(GETDATE() as float))as datetime)

或者

SELECT CONVERT(VARCHAR,GETDATE(),105)

考虑到索引列是日期时间类型的列,应该选择哪个函数?(因此我使用两次转换将日期时间 -> 日期 -> 日期时间)。


1
简而言之,select dateadd(day,datediff(day,0,@datetime),0); 的意思是将一个日期的时间部分清零,只保留日期部分。 - Hogan
1个回答

7

不选择第二和第三个选项有很好的理由。首先考虑以下问题:

select cast(floor(cast(GETDATE() as float)) as datetime)

我的问题在于,尽管它能够工作,但我找不到明确指定行为的文档。其内部格式不是浮点数,而是两个整数,因此将日期/时间转换为浮点数非常不优雅。可能存在危险的情况。
接下来:
SELECT CONVERT(VARCHAR,GETDATE(),105)

这个版本……呃!它使用了没有长度参数的varchar()。这是一个不好的习惯,不要这样做!这将会引起混淆和问题。所以,让我们考虑:

SELECT CONVERT(VARCHAR(10), GETDATE(), 105)

如果您需要字符串,那么这样做是可以的,但结果与其他查询不同。等效语句为:

SELECT CONVERT(DATE, CONVERT(VARCHAR(10), GETDATE(), 105), 105)

等等,为什么要通过字符串的中间结构呢?你最初提出的版本更简单。

唯一的缺点是它不与SQL Server 2008之前的版本兼容。如果需要与早期版本兼容,则需要使用较麻烦的:

SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)

这个功能会计算自一个虚构的“0”日期以来的天数,然后再将它们加回去。如果您不介意打字,下面的内容基本上是相同的:

SELECT DATEADD(day, DATEDIFF(day, '1900-01-01', GETDATE()), '1900-01-01')

或者通过一个中间字符串值。

SQL Server具有多个解决此功能的方法,原因是该功能非常有用,但是date日期类型仅在SQL Server 2008中引入。


感谢Gordon抽出时间并提供详细的解释... :)非常感激! - Shubham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接