Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SqlDateTime.MinValue! =DateTime.MinValue, tại sao?

Tôi nghĩ sự khác biệt giữa Ngày của SQL và .NET kiểu dữ liệu bắt nguồn từ thực tế là datetime của SQL Server kiểu dữ liệu, đó là các giá trị tối thiểu và tối đa và độ chính xác của nó cũ hơn nhiều so với kiểu dữ liệu DateTime của .NET.

Với sự ra đời của .NET, nhóm đã quyết định rằng kiểu dữ liệu Datetime phải có tính tự nhiên hơn giá trị tối thiểu và 01/01/0001 có vẻ là một lựa chọn khá hợp lý và chắc chắn là từ một ngôn ngữ lập trình , chứ không phải là cơ sở dữ liệu quan điểm, giá trị này tự nhiên hơn.

Ngẫu nhiên, với SQL Server 2008, có một số kiểu dữ liệu dựa trên ngày mới (Date, Time, DateTime2, DateTimeOffset) thực sự cung cấp phạm vi và độ chính xác tăng lên, đồng thời liên kết chặt chẽ với kiểu dữ liệu DateTime trong .NET. Ví dụ:kiểu dữ liệu DateTime2 có phạm vi ngày từ 0001-01-01 đến 9999-12-31.

Kiểu dữ liệu "datetime" tiêu chuẩn của SQL Server luôn có giá trị tối thiểu là 01/01/1753 (và thực tế là vẫn có!). Tôi phải thừa nhận rằng, tôi cũng tò mò về tầm quan trọng của giá trị này, vì vậy, một số đào bới cũng vậy .. Những gì tôi tìm thấy như sau:

Trong khoảng thời gian từ năm 1 SCN đến ngày nay, thế giới phương Tây thực sự sử dụng hai loại lịch chính:lịch Julian của Julius Caesar và lịch Gregorian của Giáo hoàng Gregory XIII. Hai lịch chỉ khác nhau về một quy tắc:quy tắc quyết định năm nhuận là gì. Trong lịch Julian, tất cả các năm chia hết cho bốn đều là năm nhuận. Trong lịch Gregory, tất cả các năm chia hết cho bốn đều là năm nhuận, ngoại trừ những năm chia hết cho 100 (nhưng không chia hết cho 400) không phải là năm nhuận. Do đó, các năm 1700, 1800 và 1900 là năm nhuận trong lịch Julian nhưng không thuộc lịch Gregorian, trong khi các năm 1600 và 2000 là năm nhuận trong cả hai lịch.

Khi Giáo hoàng Gregory XIII giới thiệu lịch của mình vào năm 1582, ông cũng chỉ thị rằng nên bỏ qua những ngày từ ngày 4 tháng 10 năm 1582 đến ngày 15 tháng 10 năm 1582 - nghĩa là, ông nói rằng ngày sau ngày 4 tháng 10 phải là ngày 15 tháng 10. Nhiều quốc gia. bị trì hoãn thay đổi, mặc dù. Nước Anh và các thuộc địa của cô ấy không chuyển từ Julian sang Gregorian tính cho đến năm 1752, vì vậy đối với họ, các ngày bị bỏ qua là từ ngày 4 tháng 9 đến ngày 14 tháng 9 năm 1752. Các quốc gia khác chuyển đổi vào thời điểm khác, nhưng năm 1582 và 1752 là những ngày liên quan cho DBMS mà chúng ta đang thảo luận.

Do đó, hai vấn đề nảy sinh với số học ngày tháng khi một người quay ngược lại nhiều năm. Đầu tiên là, những năm nhuận trước khi chuyển đổi có nên được tính theo quy tắc Julian hay Gregorian không? Vấn đề thứ hai là, những ngày bị bỏ qua nên được xử lý khi nào và như thế nào?

Đây là cách Big Eight DBMS xử lý những câu hỏi này:

  • Giả vờ như không có công tắc. Đây là điều mà Tiêu chuẩn SQL dường như yêu cầu, mặc dù tài liệu tiêu chuẩn không rõ ràng:Nó chỉ nói rằng ngày tháng bị "ràng buộc bởi các quy tắc tự nhiên cho các ngày sử dụng lịch Gregory" - bất kỳ "quy tắc tự nhiên" nào. Đây là tùy chọn mà DB2 đã chọn. Khi có một giả thuyết rằng các quy tắc của một lịch luôn được áp dụng ngay cả khi không ai biết đến lịch, thì thuật ngữ kỹ thuật là lịch "dễ hiểu" đang có hiệu lực. Vì vậy, chẳng hạn, chúng ta có thể nói rằng DB2 tuân theo một lịch Gregory sơ khai.

  • Tránh hoàn toàn vấn đề. Microsoft và Sybase đã đặt giá trị ngày tối thiểu của họ vào ngày 1 tháng 1 năm 1753, trước thời điểm Hoa Kỳ chuyển đổi lịch một cách an toàn. Điều này có thể bảo vệ được, nhưng thỉnh thoảng lại xuất hiện các khiếu nại rằng hai DBMS này thiếu một chức năng hữu ích mà các DBMS khác có và tiêu chuẩn SQL yêu cầu.

  • Chọn 1582. Đây là những gì Oracle đã làm. Người dùng Oracle sẽ thấy rằng biểu thức số học ngày 15 tháng 10 năm 1582 trừ đi ngày 4 tháng 10 năm 1582 tạo ra giá trị là 1 ngày (vì ngày 5–14 tháng 10 không tồn tại) và ngày 29 tháng 2 năm 1300 là hợp lệ (vì bước nhảy Julian- áp dụng quy tắc năm). Tại sao Oracle gặp thêm rắc rối khi Chuẩn SQL dường như không yêu cầu nó? Câu trả lời là người dùng có thể yêu cầu nó. Các nhà sử học và thiên văn học sử dụng hệ thống kết hợp này thay vì lịch Gregory. (Đây cũng là tùy chọn mặc định mà Sun đã chọn khi triển khai lớp GregorianCalendar cho Java — mặc dù tên, GregorianCalendar là một lịch kết hợp.)

Trích dẫn ở trên này được lấy từ liên kết sau:

Điều chỉnh hiệu suất SQL:Ngày trong SQL



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Danh sách các loại dữ liệu trong SQL Server 2017

  2. Cách bỏ qua lỗi khóa trùng lặp trong T-SQL (SQL Server)

  3. SQL Server BẤT KỲ Người khai thác nào được giải thích

  4. CURRENT_TIMESTAMP Ví dụ trong SQL Server (T-SQL)

  5. Không thể kết nối với máy chủ - Một lỗi liên quan đến mạng hoặc trường hợp cụ thể