如何阻止'0000-00-00 00:00:00'日期值进入我的 MySQL 表?



我在OS X 10.9.1上使用MySQL 5.5.37。我有一个类型为DATETIMENOT NULL列。在不使用触发器的情况下,如何阻止值"0000-00-00 00:00:00"进入我的列?我将接受一个CURRENT_TIMESTAMP值来代替所有的零。

我试过了:

SET sql_mode = 'NO_ZERO_DATE';

在完成上述操作后,我仍然可以在表中插入零日期。

如果不使用触发器(您声明的条件(,您就不能。然而,根据MySQL文档,

NO_ZERO_DATE模式影响服务器是否允许"0000-00-00"作为有效日期其效果还取决于是否启用了严格的SQL模式

  • 如果此模式未启用,则允许"0000-00-00",并且插入不会产生警告。

  • 如果启用了此模式,则允许"0000-00-00",并且插入会产生警告。

  • 如果启用此模式和严格模式,则不允许使用"0000-00-00",并且插入会产生错误,除非也给出IGNORE。对于INSERT IGNOREUPDATE IGNORE,允许使用"0000-00-00",插入会产生警告。

因此,您应该确保还启用了严格的SQL模式。但即便如此,正如一位评论者所指出的,这也不一定奏效。MySQL也忽略了检查约束,所以这也不起作用。如果你不想使用扳机,你就会被卡住。

SQL的正确答案是在列上添加check约束:

create table foo
(
  ...
  bar datetime not null check ( bar != '0000-00-00 00:00:00' ) ,
  ...
)

然而,mySql非常乐意解析并名义上"接受"check约束定义,但根据create table文档中的sotto-vocce注释,它会默默地忽略它们:

CHECK子句经过解析,但被所有存储引擎忽略。

为此,您可能希望添加一个before insert触发器来强制执行约束。您可能还应该强制该日期实际上是一个有效的日期,因为显然mySql甚至没有在datedatetime列中强制执行最小约束:

MySQL允许您将某些不正确的日期值存储到DATEDATETIME中列(如"2000-02-31"或"2000-02-00"(。想法是这不是工作以验证日期。如果MySQL可以存储日期值并检索完全相同的值,MySQL将其存储为给定值。如果日期完全错误(超出了服务器的存储能力("零"日期值"0000-00-00"存储在列中。

有关如何创建这样一个触发器的详细信息,请参阅此问题:Mysql CHECK Constraint

您的数据库不应负责验证脚本试图插入的数据。

它应该检查给定的数据是否与列的边界匹配(不是null、类型和长度(,但并不真正关心实际的内容

如果将列设置为NOT NULL,MySQL仍将接受空字符串00000-00-00作为string/int/date的"有效"值。

数据库应该存储数据,而不是验证它。如果你想拒绝无效数据,这是你选择的编程语言应该执行的任务。否则(言过其实(,您可以将UI与数据库连接起来,并省略任何"后端"逻辑。

相关内容

  • 没有找到相关文章

最新更新