从 MySQL 日期字段中阻止“0000-00-00”

Posted

技术标签:

【中文标题】从 MySQL 日期字段中阻止“0000-00-00”【英文标题】:Blocking '0000-00-00' from MySQL Date Fields 【发布时间】:2011-04-22 22:57:57 【问题描述】:

我有一个数据库,其中旧代码喜欢在 Date 和 DateTime 列中插入“0000-00-00”而不是实际日期。所以我有以下两个问题:

    我可以在数据库级别上做些什么来阻止它吗?我知道我可以将一列设置为非空,但这似乎并没有阻止这些零值。 检测日期字段中现有零值的最佳方法是什么?我有大约一百个表,每个表有 2-3 个日期列,我不想单独查询它们。

跟进:

默认值已设置为 null。很久以前,默认值为“0000-00-00”。一些代码仍然明确放置“0000-00-00”。我宁愿强制该代码抛出错误,以便隔离并删除它。

【问题讨论】:

我不敢相信 mysql 不支持 CHECK 约束。我打算将其发布为答案,这不是一个选择。越来越多的,我理解 MySQL 的恨。自己从来没用过。 【参考方案1】:

我可以在数据库级别做些什么来阻止这个吗?

是的,启用 NO_ZERO_DATE 模式:

SET sql_mode = 'NO_ZERO_DATE';

The behaviour is documented。此外,您可能还希望将模式设置为包括 NO_ZERO_IN_DATE...

还要确保 sql_mode 包含 STRICT_ALL_TABLES 或 STRICT_TRANS_TABLES;没有这些 NO_ZERO_IN_DATE 只会发出警告,但插入仍然成功。

检测日期字段中现有零值的最佳方法是什么?我有大约一百个表,每个表有 2-3 个日期列,我不想单独查询它们。

单独的列意味着必须单独检查它们——对此您无能为力。

【讨论】:

(这仅在插入新数据时有效 - 如果您有一个充满不良数据的数据库,则帮助不大)【参考方案2】:

假设您无法轻松修复数据和“SET sql_mode = 'NO_ZERO_DATE';”,您可以在表上创建一个视图...

CREATE VIEW filter AS
SELECT other_column, 
CASE 
  WHEN realtable.dodgy_date = 0 THEN NULL 
  ELSE realtable.dodgy_date
END AS dodgy_date
FROM realtable;

【讨论】:

【参考方案3】:

如果输入的日期无关紧要(即,只要它不为零),您可以更改列定义以使用 NOW() 作为默认值。可能不是一个理想的解决方案,但它确实满足标准: 1) 非空 2) 非零 其实我真的不为这个建议感到骄傲

【讨论】:

【参考方案4】:

您可以使列可以为空,并将 NULL 作为默认值,但听起来您已经拥有它并且它不起作用。虽然...它可能是您用来显示数据的工具不喜欢显示NULL 日期...您使用的是什么工具?还是代码检索的数据中出现了“0000-00-00”?

您可以设置一个非 null 且易于识别为默认值的默认值,例如 1900-01-01(假设您通常不处理接近此日期的日期)。

【讨论】:

【参考方案5】:

trigger 可用于强制列的值。

【讨论】:

【参考方案6】:

默认设置时间戳可能是您的一个选项,为此使用表更改语句:

ALTER TABLE mytable CHANGE date_update timestamp NOT NULL DEFAULT CURRENT_DATE()

MySQL CURRENT_DATE() documentation at w3c resource

删除零日期并将其替换为例如当前日期:

UPDATE mytable SET date_update = CURRENT_DATE() where date_update = "0000-00-00"

【讨论】:

【参考方案7】:

这是我使用的触发器:

delimiter //
CREATE TRIGGER bad_date BEFORE INSERT ON some_table
    FOR EACH ROW
        BEGIN
            IF NEW.the_date='0000-00-00' THEN 
                SET NEW.the_date= CURDATE();
            END IF;
        END;//

如果更新是一个问题,添加一个单独的触发器(更新前)来做同样的事情。

【讨论】:

以上是关于从 MySQL 日期字段中阻止“0000-00-00”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 php 创建零日期时间?

仅从日期时间字段(mysql)中提取日期并将其分配给 php 变量

如何从 MySQL 的 DATETIME 字段中仅选择日期?

用php在mysql中,如何截取最大日期和最小日期

日期字段在 PHP 和 MySQL 中被重置

查询从日期时间转换为日期mysql