欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Mysql数据库date, datetime类型设置0000-00-00默认值(default)报错问题

程序员文章站 2022-04-16 14:34:49
现象:mysql5.7版本之后,date, datetime类型设置默认值"0000-00-00",出现异常:invalid default value for 'time...

现象:mysql5.7版本之后,date, datetime类型设置默认值"0000-00-00",出现异常:invalid default value for 'time'

原因:在命令行窗口查看当前的sql_mode配置:

select @@sql_mode;

结果如下:

only_full_group_by, strict_trans_tables, no_zero_in_date, no_zero_date, 
error_for_division_by_zero, no_auto_create_user, and no_engine_substitution 

其中no_zero_in_date, no_zero_date两个选项禁止了0000这样的日期和时间。因此在mysql的配置文件中,重新设置sql_mode,去掉这两项就可以了。

解决办法

1.windows系统下:

使用 set [session|global] sql_mode='modes'

注意:session(默认选项):表示当前回话中生效;global(需重启):表示全局生效

也可以修改my.ini配置文件

***
演示: 
    set global sql_mode='only_full_group_by,strict_trans_tables, 
    error_for_division_by_zero,no_auto_create_user,no_engine_substitution'
 

1.linux系统下:

修改my.cnf文件,在[mysqld]中添加

复制代码 代码如下:
sql-mode=only_full_group_by,strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution

修改完成一定重启mysql

2.mac系统下:

在macos中默认是没有my.cnf 文件,如果需要对mysql 进行定制,拷贝/usr/local/mysql/support-files/目录 中任意一个.cnf 文件。笔者拷贝的是my-default.cnf,将它放到其他目录,按照上面修改完毕之后,更名为my.cnf,然后拷贝到/etc目录再重启下mysql就大功告成了。

sql_mode模式问题拓展

sql_mode 常用值说明

1.sql语法支持类

  • only_full_group_by

对于group by聚合操作,如果在select中的列、having或者order by子句的列,没有在group by中出现,那么这个sql是不合法的。是可以理解的,因为不在 group by 的列查出来展示会有矛盾。 在5.7中默认启用,所以在实施5.6升级到5.7的过程需要注意:

  • ansi_quotes

启用 ansi_quotes 后,不能用双引号来引用字符串,因为它被解释为识别符,作用与 ` 一样。

设置它以后,update t set f1="" ...,会报 unknown column ‘' in ‘field list 这样的语法错误。

  • pipes_as_concat

将 || 视为字符串的连接操作符而非运算符,这和oracle数据库是一样的,也和字符串的拼接函数 concat() 相类似

  • no_table_options

使用 show create table 时不会输出mysql特有的语法部分,如 engine ,这个在使用 mysqldump 跨db种类迁移的时候需要考虑

  • no_auto_create_user

字面意思不自动创建用户。在给mysql用户授权时,我们习惯使用 grant ... on ... to dbuser顺道一起创建用户。设置该选项后就与oracle操作类似,授权之前必须先建立用户。5.7.7开始也默认了。

2.数据检查类

  • no_zero_date

认为日期 ‘0000-00-00' 非法,与是否设置后面的严格模式有关。 1.如果设置了严格模式,则 no_zero_date 自然满足。但如果是 insert ignore 或 update ignore,'0000-00-00'依然允许且只显示warning 2.如果在非严格模式下,设置了no_zero_date,效果与上面一样,'0000-00-00'允许但显示warning;如果没有设置no_zero_date,no warning,当做完全合法的值。3.no_zero_in_date情况与上面类似,不同的是控制日期和天,是否可为 0 ,即 2010-01-00 是否合法。

  • no_engine_substitution

使用 alter table或create table 指定 engine 时, 需要的存储引擎被禁用或未编译,该如何处理。启用no_engine_substitution时,那么直接抛出错误;不设置此值时,create用默认的存储引擎替代,atler不进行更改,并抛出一个 warning。

  • strict_trans_tables

设置它,表示启用严格模式。

 注意 strict_trans_tables 不是几种策略的组合,单独指 insert、update出现少值或无效值该如何处理: 把 ‘' 传给int,严格模式下非法,若启用非严格模式则变成0,产生一个warning
out of range,变成插入最大边界值

a value is missing when a new row to be inserted does not contain a value for a non-null column that has no explicit default clause in its definition

mysql5.0以上版本支持三种sql_mode模式: set @@sql_mode=xxx模式名;

我们常设置的 sql_mode 是 ansi、strict_trans_tables、traditional,其中ansi和traditional是上面的几种组合。

3.ansi模式:宽松模式,对插入数据进行校验,如果不符合定义类型或者长度,对数据类型调整或截断保存,报warning警告.

4.traditional模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误.用于事务时,会进行事务的回滚.

3.strict_trans_tables模式:严格模式,进行数据的严格校验,错误数据不能插入,报error错误。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。