12

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

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

跟进:

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

4

7 回答 7

15

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

是的,启用 NO_ZERO_DATE 模式:

SET sql_mode = 'NO_ZERO_DATE';

该行为已记录在案。此外,您可能还希望将模式设置为包括 NO_ZERO_IN_DATE ...

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

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

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

于 2010-10-08T15:19:02.897 回答
1

假设你不能轻易修复数据和“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;
于 2010-10-08T15:29:55.713 回答
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;//

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

于 2014-08-21T13:38:17.537 回答
0

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

于 2010-10-08T15:16:20.117 回答
0

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

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

于 2010-10-08T15:17:19.197 回答
0

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

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

w3c 资源中的 MySQL CURRENT_DATE() 文档

要删除零日期并将其替换为例如当前日期,请执行以下操作:

UPDATE mytable SET date_update = CURRENT_DATE() where date_update = "0000-00-00"
于 2014-05-20T09:17:46.330 回答
0

触发器可用于强制列的值。

于 2010-10-08T15:45:46.373 回答