Incorrect datetime value

简介:

今天在开发库上给一个表添加字段时候,发现居然报错:

root@DB 06:14:42>ALTER TABLE `DB`.` user` ADD COLUMN `status_mode` TINYINT UNSIGNED AFTER ` test_id`;

ERROR 1292 (22007): Incorrect datetime value: ‘0000-00-00 00:00:00’ for column ‘GMT_CLEANUP’ at row 2;

查找error的信息:

$perror 1292

错误:1292 SQLSTATE: 22007 (ER_TRUNCATED_WRONG_VALUE)

消息:截短了不正确的%s值: ‘%s’

这种解释有点让人不明白。

接着想到mysql中alter table add column运行时会对原表进行临时复制,在副本上进行更改,然后删除原表,再对新表进行重命名。那么报错的原因就是在ddl过程中copy原表,在copy表的过程中发现有表中GMT_CLEANUP的数据为’0000-00-00 00:00:00’,mysql认为该数据是不合法的数据:

root@DB06:39:56>select GMT_CLEANUP from user where GMT_CLEANUP like ‘%00%’ limit 2

-> ;

+———————+

| GMT_CLEANUP         |

+———————+

| 0000-00-00 00:00:00 |

| 0000-00-00 00:00:00 |

+———————+

2 rows in set, 1 warning (0.00 sec)

第一个问题:那么为什么mysql认为0000-00-00 00:00:00是不正确的?

第二个问题0000-00-00 00:00:00是怎么被插入到数据库中的,应用有这个需求吗?

对于第一个问题,还是需要回到mysql中对日期时间的定义上,在官方文档上说明MySQL允许将’0000-00-00’保存为“伪日期”(如果不使用NO_ZERO_DATE SQL模式)。这在某些情况下比使用NULL值更方便(并且数据和索引占用的空间更小)。那么接下来,就是看看sql_mode中的参数了;

root@DB06:40:48>show variables like ‘sql_mode’;

+—————+——————————————————————————————————————————-+

| Variable_name | Value                                                                                                                         |

+—————+——————————————————————————————————————————-+

| sql_mode      | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER |

+—————+——————————————————————————————————————————-+

1 row in set (0.00 sec)

参数中含有no_zero_date,

在严格模式,不要将 ‘0000-00-00’做为合法日期。你仍然可以用IGNORE选项插入零日期。在非严格模式,可以接受该日期,但会生成警告。

NO_ZERO_IN_DATE

在严格模式,不接受月或日部分为0的日期。如果使用IGNORE选项,我们日期插入’0000-00-00’。在非严格模式,可以接受该日期,但会生成警告。

问题可以解决了,改变sql_mode:将no_zero_date和no_zero_in_date去掉:

root@DB 07:05:21>set global sql_mode=’STRICT_TRANS_TABLES,STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER’;

Query OK, 0 rows affected (0.00 sec)

root@DB 07:07:01>show variables like ‘%sql_mode%’;

+—————+——————————————————————————————————————————-+

| Variable_name | Value                                                                                                                         |

+—————+——————————————————————————————————————————-+

| sql_mode      | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER |

+—————+——————————————————————————————————————————-+

1 row in set (0.00 sec)

虽然去掉了no_zero_date和no_zero_in_date,但在参数中还有这两个参数的存在,于是exit该会话,在查看参数的值依然无效:

root@DB 07:07:10>exit

Bye

[MM-Writable@dev ~]

$mysql -uroot DB

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 23505133

Server version: 5.1.37-log Source distribution

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

root@DB 07:07:41>show variables like ‘%sql_mode%’;

+—————+——————————————————————————————————————————-+

| Variable_name | Value                                                                                                                         |

+—————+——————————————————————————————————————————-+

| sql_mode      | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER |

+—————+——————————————————————————————————————————-+

1 row in set (0.00 sec)

为什么会出现这种情况,是不是参数设置的不对,查看了其他库中sql_mode的参数,都没有设置,唯独这个库中sql_mode设置了,看来需要对sql_mode做详细的了解了:

简单说sql_mode是设置mysql应该支持哪些sql语法,以及哪种数据验证检查。这样可以更容易地在不同的环境中使用MySQL,并结合其它数据库服务器使用MySQL。可以通过用SET [SESSION|GLOBAL] sql_mode=’modes’语句设置sql_mode变量来更改SQL模式。设置 GLOBAL变量时需要拥有SUPER权限,并且会影响从那时起连接的所有客户端的操作。设置SESSION变量只影响当前的客户端。任何客户端可以随时更改自己的会话 sql_mode值。

当前数据库的sql_mode中有:

STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER

这些值,这是将sql_mode设为了:TRADITIONAL模式,所以只去除NO_ZERO_IN_DATE,NO_ZERO_DATE是不行的,还要去除TRADITIONAL;

root@DB 07:07:43>set global sql_mode=’STRICT_TRANS_TABLES,STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER’;

Query OK, 0 rows affected (0.00 sec)

退出来后,重新登录:

root@DB 07:20:47>show variables like ‘%sql_mode%’;

+—————+————————————————————————————–+

| Variable_name | Value                                                                                |

+—————+————————————————————————————–+

| sql_mode      | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER |

+—————+————————————————————————————–+

1 row in set (0.00 sec)

root@DB 07:20:48>ALTER TABLE `DB`.`ali_mall_user` ADD COLUMN `status_mode` TINYINT UNSIGNED AFTER `op_invest_id`;

Query OK, 106 rows affected (0.66 sec)

Records: 106  Duplicates: 0  Warnings: 0

已经看到可以修改表的结构了,现在mysql允许ddl了。

对于第二个问题:为什么会插入0000-00-00 00:00:00?

。严格模式允许日期使用“零”部分,例如’2004-04-00’或“零”日期。要想禁止,应在严格模式基础上,启用NO_ZERO_IN_DATE和NO_ZERO_DATE SQL模式。

。每个时间类型有一个有效值范围和一个“零”值,当指定不合法的MySQL不能表示的值时使用“零”值。

。无效DATETIME、DATE或者TIMESTAMP值被转换为相应类型的“零”值(‘0000-00-00 00:00:00’、’0000-00-00’或者00000000000000)。

从上面的sql_mode中可以看到在严格模式(启用STRICT_TRANS_TABLES或STRICT_ALL_TABLES模式)是可以插入:0000-00-00 00:00:00’,但是后面还启动了TRADITIONAL,TRADITIONAL中还有NO_ZERO_IN_DATE和NO_ZERO_DATE 模式,所以前期插入了0000-00-00 00:00:00数据,后面有改动了sql_mode,最后导致前面插入插入的数据变为了不合法,所以才会出现上面总总问题。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
5月前
|
存储 人工智能 机器人
2026年阿里云OpenClaw一键部署详细教程,快速拥有OpenClaw超级助理!
2026年,AI数字员工已成现实!阿里云OpenClaw提供一键部署方案,3步即可搭建24小时在线的专属AI助理。本文含分步实操+高频避坑指南,支持钉钉/飞书集成、技能扩展与定时任务,个人及中小企业零门槛上手。
1384 3
|
4月前
|
Arthas 监控 数据可视化
深度剖析:Java 并发三大量难题 —— 死锁、活锁、饥饿全解
本文深入剖析Java并发中三大顽疾:死锁(线程永久阻塞)、活锁(线程忙等无效运行)、饥饿(低优先级线程长期得不到资源)。厘清其本质区别、触发条件、实战案例及jstack/Arthas等排查方案,并给出统一锁序、定时锁、公平锁等落地解决策略。
423 1
|
5月前
|
存储 机器学习/深度学习 自然语言处理
56.大模型应用:大模型瘦身:量化、蒸馏、剪枝的基础原理与应用场景深度解析.56
本文深入对比大模型轻量化三大核心技术:量化(降精度,快部署)、蒸馏(知识迁移,高精度)、剪枝(删冗余,结构精简)。详解原理、分类、适用场景、代码实现及选型建议,助开发者根据硬件条件、精度要求与落地周期科学决策。
1498 16
|
数据采集 存储 人工智能
【AI 初识】AI 的挑战和局限性
【5月更文挑战第2天】【AI 初识】AI 的挑战和局限性
【AI 初识】AI 的挑战和局限性
|
SQL 关系型数据库 MySQL
(十八)MySQL排查篇:该如何定位并解决线上突发的Bug与疑难杂症?
前面《MySQL优化篇》、《SQL优化篇》两章中,聊到了关于数据库性能优化的话题,而本文则再来聊一聊关于MySQL线上排查方面的话题。线上排查、性能优化等内容是面试过程中的“常客”,而对于线上遇到的“疑难杂症”,需要通过理性的思维去分析问题、排查问题、定位问题,最后再着手解决问题,同时,如果解决掉所遇到的问题或瓶颈后,也可以在能力范围之内尝试最优解以及适当考虑拓展性。
1811 3
|
PHP 数据安全/隐私保护
PHP基于 OpenSSL 实现国密 SM4 加解密
PHP基于 OpenSSL 实现国密 SM4 加解密
3082 0
|
Linux Perl
源码安装openssl遇到的一些问题及解决方式
本文总结了在源码安装openssl过程中遇到的一些问题及其解决方法,包括缺少libssl.so.1.1库文件、缺少Perl模块以及权限不足时如何指定安装目录等问题。
3811 0
|
小程序 开发工具 开发者
微信小程序入门->小程序简介,小程序商城项目案例,小程序入门案例及目录结构
微信小程序入门->小程序简介,小程序商城项目案例,小程序入门案例及目录结构
491 0
微信小程序入门->小程序简介,小程序商城项目案例,小程序入门案例及目录结构
|
Linux
Linux命令(130)之hwclock
Linux命令(130)之hwclock
1181 1

热门文章

最新文章