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

时间:2010-10-08 15:12:39

标签: mysql datetime date data-cleansing

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

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

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

7 个答案:

答案 0 :(得分:12)

  

我可以在db级别上做些什么来阻止它吗?

是,启用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个日期列,我不想单独查询它们。

单独的列表示必须单独检查 - 您无能为力。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以将列设为可为空并将NULL作为默认值,但听起来您已经拥有了它并且它无效。尽管如此......它可能是您用来显示数据的工具,不喜欢显示NULL日期...您使用的是什么工具?或者“代码”中的'0000-00-00'显示在数据中吗?

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

答案 3 :(得分:0)

假设您无法轻松修复数据并且“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;

答案 4 :(得分:0)

trigger可用于强制列的值。

答案 5 :(得分:0)

默认情况下设置时间戳可能是一个选项,请使用表更改语句:

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"

答案 6 :(得分:0)

这是我使用的触发器:

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;//

如果需要更新,请添加单独的触发器(BEFORE UPDATE)以执行相同的操作。