我正在修改查询,这是我的脚本:
select
CASE When EndDate='1/1/1900'
THEN NULL
ELSE EndDate END,*
from Members
此脚本只是比较日期,如果是“1/1/1900”则返回 null
,否则返回日期。
我可以在我的数据库中看到日期以以下格式存储:
1900-01-01 00:00:00.000
问题是,当我的模式与存储的模式不同时,SQL Server 如何匹配这样的日期。同样在日期格式中,我没有传递时间元素。
最佳答案
由于 data type precedence (since datetime has higher precedence than string types),SQL Server 将您传递的字符串文字 ('1/1/1900'
) 转换为日期时间值。如果您传递无效日期作为字符串,例如'2/31/1900'
,您将收到转换错误 (Msg 242
),因为 SQL Server 不知道 2 月 31 日意味着什么。它不会尝试匹配看起来像您传递的内容的字符串,它会将两者转换为其日期的内部表示形式(更多内容请参见我的评论)。
在具体处理日期时,请停止考虑格式,除非您传递字符串文字时,m/d/y
(或者是d/m/y
?) 是一种糟糕的格式。使用起来更安全:
YYYYMMDD
您的查询应为:
SELECT CASE When EndDate = '19000101'
THEN NULL ELSE EndDate END, ...other columns...
FROM dbo.Members;
这样,当您传递像 9 月 8 日这样的日期时,SQL Server、其他读者等就不会误解它。09/08/2013
是 9 月 8 日还是 8 月 9 日?取决于您位于世界的哪个部分,对吧?在你的情况下,这是可以的,因为日期和月份是相同的,但情况并不总是如此。请参阅以下文章:
(请、请、请完整阅读该链接。)
最后,如果您使用 DATETIME/SMALLDATETIME
并查找特定日期的值,则根本不应该使用相等性,而应该使用范围查询。例如,要查找 EndDate
为 2013 年 4 月 15 日的所有行(无论时间如何),您可以这样说:
WHERE EndDate >= '20130415'
AND EndDate < '20130416'
( Read this link to understand why you don't want to use BETWEEN
here .)
如果您使用的是 SQL Server 2008 或更高版本,您仍然可以使用 CONVERT
在此列上实现可控制性,但这是一个罕见的异常(exception) - 通常您不想对某个列使用函数专栏。
WHERE CONVERT(DATE, EndDate) = '20130415'
其他一些评论 - 与您的问题不直接相关,但对您的代码进行了外围观察:
关于sql-server - SQL Server 如何将日期与字符串文字进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16027045/