B.4.4.2 使用 DATE 列的问题

DATE值的格式为'YYYY-MM-DD'。根据标准 SQL,不允许使用其他格式。您应该在UPDATEtable 达式和SELECT语句的WHERE子句中使用此格式。例如:

SELECT * FROM t1 WHERE date >= '2003-05-05';

为方便起见,如果在数字上下文中使用日期,则 MySQL 自动将日期转换为数字,反之亦然。 MySQL 还允许在更新时和WHERE子句中使用“松弛”字符串格式,该子句将日期与DATEDATETIMETIMESTAMP列进行比较。 “轻松”格式 table 示任何标点符号都可以用作部分之间的分隔符。例如,'2004-08-15''2004#08#15'是等效的。 MySQL 也可以转换不包含分隔符的字符串(例如'20040815'),只要它可以作为日期即可。

当您将DATETIMEDATETIMETIMESTAMP与带有<<==>=>BETWEEN运算符的常量字符串进行比较时,MySQL 通常会将字符串转换为内部长整数以便于比较(以及多一点“放松”的字符串检查)。但是,此转换受以下 exception 的约束:

  • 比较两列时

  • DATETIMEDATETIMETIMESTAMP列与 table 达式进行比较时

  • 当您使用除刚刚列出的之外的任何比较方法时,例如INSTRCMP()

对于这些异常,通过将对象转换为字符串并执行字符串比较来完成比较。

为了安全起见,假设您要将字符串与字符串进行比较,则假定将字符串作为字符串进行比较,并使用适当的字符串函数。

特殊的“零”日期'0000-00-00'可以作为'0000-00-00'.进行存储和检索。当通过 Connector/ODBC 使用'0000-00-00'日期时,它会自动转换为NULL,因为 ODBC 无法处理这种日期。

由于 MySQL 执行上述转换,因此以下语句起作用(假设idateDATE列):

INSERT INTO t1 (idate) VALUES (19970505);
INSERT INTO t1 (idate) VALUES ('19970505');
INSERT INTO t1 (idate) VALUES ('97-05-05');
INSERT INTO t1 (idate) VALUES ('1997.05.05');
INSERT INTO t1 (idate) VALUES ('1997 05 05');
INSERT INTO t1 (idate) VALUES ('0000-00-00');

SELECT idate FROM t1 WHERE idate >= '1997-05-05';
SELECT idate FROM t1 WHERE idate >= 19970505;
SELECT MOD(idate,100) FROM t1 WHERE idate >= 19970505;
SELECT idate FROM t1 WHERE idate >= '19970505';

但是,以下语句不起作用:

SELECT idate FROM t1 WHERE STRCMP(idate,'20030505')=0;

STRCMP()是字符串函数,因此它将idate转换为'YYYY-MM-DD'格式的字符串并执行字符串比较。它不会将'20030505'转换为日期'2003-05-05'并执行日期比较。

如果启用ALLOW_INVALID_DATES SQL 模式,则 MySQL 允许您存储仅进行有限检查的日期:MySQL 仅要求日期在 1 到 31 之间,月份在 1 到 12 之间。这使得 MySQL 对于在三个不同字段中获取年,月和日并且想要存储用户插入的内容(没有日期验证)的 Web 应用程序来说,这非常方便。

MySQL 允许您存储日期或星期几为零的日期。如果要将生日存储在DATE列中,并且只知道该日期的一部分,这将很方便。要禁止日期中的零个月或日部分,请启用NO_ZERO_IN_DATE模式。

MySQL 允许您将'0000-00-00'的“零”值存储为“虚拟日期”。在某些情况下,这比使用NULL值更方便。如果不能将要存储在DATE列中的日期转换为任何合理的值,则 MySQL 将存储'0000-00-00'。要禁止'0000-00-00',请启用NO_ZERO_DATE模式。

要让 MySQL 检查所有日期并仅接受合法日期(除非被IGNORE覆盖),请将sql_mode系统变量设置为"NO_ZERO_IN_DATE,NO_ZERO_DATE"