use*_*510 9 t-sql sql-server datetime sql-server-2005 sql-server-2008
我正在修改一个查询,这是我的脚本:
select
CASE When EndDate='1/1/1900'
THEN NULL
ELSE EndDate END,*
from Members
Run Code Online (Sandbox Code Playgroud)
此脚本只是比较日期,如果是'1/1/1900'则返回,null否则返回日期.
我可以在我的数据库中看到日期存储的格式如下:
1900-01-01 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
问题是当我的模式与存储模式不同时,SQL Server如何匹配日期.同样在日期格式中,我没有传递时间元素.
Aar*_*and 18
SQL Server converts the string literal you are passing ('1/1/1900') to a datetime value due to data type precedence (since datetime has higher precedence than string types). If you pass an invalid date as your string, e.g. '2/31/1900', you will get a conversion error (Msg 242) because SQL Server doesn't know what February 31st means. It is not trying to match a string that looks like what you are passing, it converts both to its internal representation for dates (more on that in my comment).
When dealing with dates specifically, stop thinking about a format except that when you pass string literals, m/d/y (or is that d/m/y?) is a terrible format to use. Much safer to use:
YYYYMMDD
Run Code Online (Sandbox Code Playgroud)
Your query should read:
SELECT CASE When EndDate = '19000101'
THEN NULL ELSE EndDate END, ...other columns...
FROM dbo.Members;
Run Code Online (Sandbox Code Playgroud)
This way, when you pass a date like September 8th, it is not misinterpreted by SQL Server, other readers, etc. Is 09/08/2013 September 8th or August 9th? Depends on what part of the world you're in, right? In your case it's okay because the day and month are the same, but this won't always be the case. Please see the following article:
(Please, please, please read that link in its entirety.)
Finally, if you are using DATETIME/SMALLDATETIME and are looking for values from a specific day, you should not be using equality at all, but rather a range query. For example, to find all the rows where EndDate falls on April 15th, 2013, regardless of time, you would say:
WHERE EndDate >= '20130415'
AND EndDate < '20130416'
Run Code Online (Sandbox Code Playgroud)
(Read this link to understand why you don't want to use BETWEEN here.)
如果您使用的是SQL Server 2008或更高版本,您仍然可以在此列上实现sargability CONVERT,但这是一个罕见的例外 - 通常您不希望对列使用函数.
WHERE CONVERT(DATE, EndDate) = '20130415'
Run Code Online (Sandbox Code Playgroud)
其他一些评论 - 与您的问题没有直接关系,但有关您的代码的外围观察: