Проблемы с использованием столбцов типа DATE


Значения типа DATE имеют формат YYYY-MM-DD; согласно стандарту ANSI SQL, никакой другой формат не допускается. Пользователь должен применять этот формат в выражениях UPDATE и в определении WHERE операторов SELECT. Например:

mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';

Из соображений удобства MySQL автоматически преобразовывает дату в число, если дата используется в числовом контексте (и наоборот). Благодаря своей «разумности» MySQL допускает также «мягкую» строковую форму при обновлении и в определении WHERE, сравнивающем дату со столбцом типа TIMESTAMP, DATE или DATETIME ("мягкая" форма означает, что для разделения составляющих даты можно использовать любой знак пунктуации; например, 1998-08-15 и 1998#08#15 эквивалентны). MySQL может также преобразовывать в даты строки, не содержащие разделителей (наподобие 19980815), при условии, что представляемая строкой дата не лишена смысла.

Специальная дата 0000-00-00 может записываться и извлекаться в виде 0000-00-00. При использовании даты 0000-00-00 из MyODBC она будет автоматически преобразована в NULL в версии MyODBC 2.50.12 и выше, так как ODBC не обеспечивает обработку такого рода дат.

Поскольку в MySQL выполняются описанные выше преобразования, следующие команды будут работать:

mysql> INSERT INTO tbl_name (idate) VALUES (19970505);
mysql> INSERT INTO tbl_name (idate) VALUES ('19970505');
mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05');
mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05');
mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05');
mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00');
mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT MOD(idate,100) FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505';

Однако приведенные ниже команды работать не будут:

mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;

STRCMP() - строковая функция, следовательно, она преобразует idate в строку и сравнивает строки. Функция не станет преобразовывать 19970505 в дату и сравнивать даты.

Заметим, что MySQL осуществляет очень ограниченную проверку правильности дат, поэтому такая некорректная дата, как 1998-2-31, будет занесена в базу.

Поскольку MySQL пакует даты для сохранения, он не может сохранить любую дату, так как она может не поместится в результирующий буфер. Правила принятия дат следующие:

  • Если MySQL может хранить и выбирать заданную дату, неправильная дата принимается для столбцов DATE и DATETIME.

  • Все значения дней между 0-31 принимаются для любой даты, это удобно для приложения, где вы запрашиваете год, месяц и день в 3-х различных полях.

  • День или месяц могут быть нулем. Это удобно когда вы хотите хранить дату рождения в столбце DATE и знаете только часть ее.

Если же дату нельзя преобразовать в какое-нибудь разумное значение, в поле типа DATE заносится 0. Проверка правильности дат не делается - в основном из соображений, связанных со скоростью: мы считаем, что проверкой дат должно заниматься приложение, а не сервер.

Навигация