Máy chủ SQL chuyển đổi chuỗi ký tự bạn đang chuyển ('1/1/1900'
) thành giá trị ngày giờ do data type precedence (since datetime has higher precedence than string types). Nếu bạn vượt qua ngày không hợp lệ làm chuỗi của mình, ví dụ: '2/31/1900'
, bạn sẽ nhận được một lỗi chuyển đổi (Msg 242
) bởi vì SQL Server không biết những gì có nghĩa là 31 tháng hai. Nó không cố gắng để phù hợp với một chuỗi giống như những gì bạn đang truyền, nó chuyển đổi cả hai để đại diện nội bộ của nó cho ngày (thêm vào đó trong bình luận của tôi).
Khi giao dịch với số ngày cụ thể, ngừng suy nghĩ về một định dạng ngoại trừ việc khi bạn vượt qua xâu, m/d/y
(hoặc là d/m/y
?) Là một định dạng khủng khiếp để sử dụng. Nhiều an toàn hơn để sử dụng:
YYYYMMDD
truy vấn của bạn nên đọc:
SELECT CASE When EndDate = '19000101'
THEN NULL ELSE EndDate END, ...other columns...
FROM dbo.Members;
Bằng cách này, khi bạn vượt qua một ngày như ngày 8 tháng 9, nó không phải là hiểu sai bởi SQL Server, độc giả khác, vv là 09/08/2013
ngày 8 tháng 9 hoặc ngày 9 tháng 8? Phụ thuộc vào phần nào của thế giới bạn đang ở, phải không? Trong trường hợp của bạn thì không sao cả vì ngày và tháng là như nhau, nhưng điều này không phải lúc nào cũng đúng. Xin vui lòng xem bài viết sau:
http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx
(. Xin vui lòng, xin vui lòng, xin vui lòng đọc liên kết trong toàn bộ)
Cuối cùng, nếu bạn đang sử dụng DATETIME/SMALLDATETIME
và đang tìm kiếm các giá trị từ một ngày cụ thể, bạn không nên sử dụng bình đẳng ở tất cả, mà đúng hơn là một truy vấn phạm vi. Ví dụ, để tìm tất cả các hàng nơi EndDate
rơi vào ngày 15 Tháng Tư năm 2013, bất kể thời gian, bạn sẽ nói: (. Read this link to understand why you don't want to use BETWEEN
here)
WHERE EndDate >= '20130415'
AND EndDate < '20130416'
Nếu bạn đang ở trên SQL Server 2008 hoặc tốt hơn, bạn vẫn có thể đạt được sargability trên cột này với CONVERT
, nhưng đây là một ngoại lệ hiếm - thường bạn không muốn sử dụng một hàm chống lại một cột.
WHERE CONVERT(DATE, EndDate) = '20130415'
Một vài ý kiến khác - không liên quan trực tiếp đến câu hỏi của bạn, nhưng ngoại vi quan sát về mã của bạn:
- Always use the schema prefix
- Never use
SELECT *
in production
Nhìn vào 'chức năng DATEPART'. Xem http://msdn.microsoft.com/en-us/library/aa258265(v=sql.80).aspx –
@ PM77-1 bạn đã đọc câu hỏi chưa? –
Vâng ... tôi đã làm. Mắc lỗi. Có nghĩa là 'CONVERT'. –