2011-07-30 42 views
20

Tôi muốn cung cấp cho người dùng khả năng giới thiệu các ngày chưa hoàn thành (ví dụ: chỉ năm 2005 hoặc tháng 1 năm 1998) nhưng cũng là ngày đầy đủ theo năm, tháng, ngày. Tôi có thể thực hiện điều này bằng cách sử dụng một trường ngày tháng trong DB không?Lưu trữ ngày không đầy đủ trong trường ngày tháng

Tôi đã thử UPDATE tableA SET mydate = '2001-00-00' và có vẻ như hoạt động (không có lỗi) nhưng tôi không chắc liệu điều này có đúng không. Trong nội bộ tôi giả sử một dấu thời gian được sử dụng để làm thế nào MySQL có thể đại diện cho những 0?

+0

Bạn nhận được gì khi bạn truy vấn 'SELECT mydate FROM tableA'? – phlogratos

+0

Giá trị chính xác, tức là 2001-00-00. Nỗi lo của tôi chỉ là tôi đang khai thác một số hành vi tiêu chuẩn không phụ thuộc vào một số thủ thuật có thể nghỉ một ngày hoặc không hoạt động trong một số trường hợp nhất định. –

Trả lời

22

Có một lưu ý nhỏ trong documentation for the DATE_FORMAT() về MySQL cho phép ngày không đầy đủ:

Ranges cho tháng và ngày specifiers bắt đầu với zero do thực tế rằng MySQL cho phép lưu trữ các số ngày không đầy đủ như ' 2014-00-00 '.

Như đã chỉ ra bởi @wonk0, MySQL sẽ tập hợp số ngày không hợp lệ để 0000-00-00 00:00:00 khi ALLOW_INVALID_DATES không được thiết lập. Tuy nhiên, ngay cả khi ALLOW_INVALID_DATES không được đặt, việc chèn một năm hợp lệ với tháng và ngày được đặt bằng 0 không xuất hiện để kích hoạt hành vi này - ít nhất là không có trong thử nghiệm của tôi (MySQL 5.1.54-1ubuntu4). Tôi đã sử dụng tính năng này trước đây mà không có bất kỳ vấn đề nào, nhưng tôi đã không thể tìm thấy bất kỳ tài liệu chi tiết nào khác mô tả hành vi này đầy đủ.

So sánh ngày/giờ cũng có vẻ hoạt động như mong đợi: ví dụ: 2011-01-00 > 2011-00-002011-00-01 > 2011-00-00 làm như bạn mong đợi.

CẬP NHẬT

Xem this answer (bằng cách khác Mike) cho một câu hỏi tương tự. Nó trỏ đến một chiết xuất từ ​​The Definitive Guide để MySQL 5:

Trong các phiên bản cũ của MySQL, DATE và các kiểu dữ liệu DATETIME đã chỉ một số lượng hạn chế của loại hình kiểm tra. Giá trị từ 0 đến 12 cho tháng và 0 và 31 cho các ngày thường được cho phép. Tuy nhiên, nó là trách nhiệm của chương trình khách hàng để cung cấp dữ liệu chính xác. (Ví dụ: , 0 là giá trị được phép cho một tháng hoặc ngày, để cung cấp khả năng lưu trữ dữ liệu không đầy đủ hoặc không xác định.)

Bắt đầu với MySQL 5.0.2, có xác thực kỹ lưỡng hơn, vì vậy chỉ có thể lưu trữ dữ liệu hợp lệ. Vẫn được phép là tháng và giá trị ngày 0, cũng như ngày 0000-00-00.

+1

Giả sử rằng một dấu thời gian được sử dụng để lưu trữ ngày do đó không chính xác? Bởi vì tôi không thấy làm thế nào bạn có thể đại diện cho 2011-00-00 như một dấu thời gian. –

+1

@Omar Kohl: Vâng, tôi nghĩ rằng giả định là không chính xác. Dấu 'TIMESTAMP' có phạm vi nhỏ hơn 'DATETIME'. 'DATETIME' sử dụng 8 byte, trong khi' TIMESTAMP' sử dụng 4 byte. Xem [Yêu cầu lưu trữ loại dữ liệu] (http://dev.mysql.com/doc/refman/5.5/en/storage-requirements.html#id918335) – Mike

+1

Câu trả lời hay nhất, điều tốt nhất tôi đã tìm thấy ở khắp mọi nơi. –

2

Vâng, nếu bạn đã sử dụng trường ngày thì bạn nên mong đợi những 0 đó. Một cách bạn có thể loại bỏ chúng là sử dụng lựa chọn varchar. Tuy nhiên, tốt hơn là sử dụng một trường ngày kể từ đó những gì được lưu trữ ở đó.

Nếu bạn phải cho phép người dùng nhập vào một ngày không đầy đủ thì nó có phải là một varchar và trong trường hợp đó bạn có thể định dạng đầu vào với kịch bản và cửa hàng của bạn trong cột đó

+0

Đó sẽ là phương sách cuối cùng của tôi. Tất nhiên có những thứ trong định dạng ngày luôn đẹp hơn để đặt hàng vv –

+1

vâng thay vì cho phép người dùng định dạng ngày, tôi khuyên bạn chỉ cho phép sql định dạng 'datetimestamp' hiện tại có – DaMainBoss

+0

+1 điểm rất tốt. Dats những gì tôi đã làm –

1

phần lưu trữ của ngày phụ thuộc vào Chế độ sql MySQL đang chạy. Vui lòng đọc http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html, đặc biệt là về các ngày không hợp lệ trong http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_allow_invalid_dates.

+1

"ALLOW_INVALID_DATES: Không thực hiện kiểm tra đầy đủ các ngày. Chỉ kiểm tra xem tháng có nằm trong khoảng từ 1 đến 12 và trong ngày nằm trong khoảng từ 1 đến 31 hay không". Trong trường hợp này, nó không áp dụng vì cả tháng lẫn ngày đều nằm trong phạm vi đó ... (00 cả hai) –

+0

'Chỉ kiểm tra xem tháng nằm trong khoảng từ 1 đến 12 và ngày nằm trong khoảng từ 1 đến 31' Tại sao điều này cho phép một tháng hoặc một ngày 0? – phlogratos

Các vấn đề liên quan