MySQL运维实战(4.5) SQL_MODE之NO_ZERO_DATE和NO_ZERO_IN_DATE

俊达2年前技术文章1510

NO_ZERO_DATE:日期中不允许'0000-00-00'

NO_ZERO_IN_DATE:日期中年、月或日不允许为0,如不允许'2021-00-01', '2021-01-00'

date, datetime, timestamp都受这2个sql mode的影响

这2个sql mode需要跟strict模式一起使用。如果不开启strict模式,异常数据还是能写入到数据库。


NO_ZERO_DATE


只设置NO_ZERO_DATE, 异常数据会产生Warning,但是数据能写入

mysql> create table t_date( a date);
Query OK, 0 rows affected (0.01 sec)

-- 只设置NO_ZERO_DATE, 异常数据会产生Warning,但是数据能写入
mysql> set sql_mode='NO_ZERO_DATE';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t_date values(0);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'a' at row 1 |
+---------+------+--------------------------------------------+
1 row in set (0.01 sec)

mysql> select * from t_date;
+------------+
| a          |
+------------+
| 0000-00-00 |
+------------+
1 row in set (0.00 sec)

mysql> insert into t_date values('2021-00-00');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_date;
+------------+
| a          |
+------------+
| 0000-00-00 |
| 2021-00-00 |
+------------+
2 rows in set (0.00 sec)


NO_ZERO_IN_DATE

-- 设置NO_ZERO_IN_DATE, 日期、月份为0的数据会触发warning
mysql> set sql_mode='NO_ZERO_IN_DATE';
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> insert into t_date values('2022-01-00');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'a' at row 1 |
+---------+------+--------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from t_date;
+------------+
| a          |
+------------+
| 0000-00-00 |
| 2021-00-00 |
| 0000-00-00 |
+------------+
3 rows in set (0.00 sec)


STRICT模式

同时设置STRICT和NO_ZERO_DATE,NO_ZERO_IN_DATE,才能避免写入异常日期数据:

-- 增加STRICT模式,异常数据无法写入
mysql> set sql_mode='NO_ZERO_IN_DATE,NO_ZERO_DATE,STRICT_ALL_TABLES';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t_date values(0);
ERROR 1292 (22007): Incorrect date value: '0' for column 'a' at row 1

mysql> insert into t_date values('2023-00-00');
ERROR 1292 (22007): Incorrect date value: '2023-00-00' for column 'a' at row 1

mysql> insert into t_date values('2023-01-02');
Query OK, 1 row affected (0.00 sec)


如果只设置STRICT模式,不设置NO_ZERO_IN_DATE,NO_ZERO_DATE,还是能写入为0的日期:

mysql> set sql_mode='STRICT_ALL_TABLES';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t_date values('');
ERROR 1292 (22007): Incorrect date value: '' for column 'a' at row 1

mysql> select * from t_date;
Empty set (0.00 sec)

mysql> insert into t_date values(0);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_date;
+------------+
| a          |
+------------+
| 0000-00-00 |
+------------+
1 row in set (0.00 sec)


总结

建议同时设置NO_ZERO_IN_DATE,NO_ZERO_DATE和STRICT_TRANS_TABLES,可以避免写入异常的日期数据。




相关文章

MySQL运维实战之备份和恢复(8.5)xtrabackup恢复增量备份

恢复增量备份时,需要先对基础全量备份进行恢复,然后再依次按增量备份的时间进行恢复。这个例子中,相关备份文件的目录结构如下:/data/backup ├── full │ &nb...

MySQL运维实战(6)用户认证插件caching_sha2_password

MySQL用户认证可以使用几种不同的方式,创建用户时可以制定认证方式:create user 'username'@'%' identif...

MySQL运维实战(4.1) MySQL表存储引擎

MySQL表的特点和其他数据库如Oracle、SQL Server相比,mysql有一些特点:MySQL使用插件式存储引擎,同一个数据库中的表可以使用不同的存储引擎。存储引擎决定了表的物理存储格式。表...

MySQL运维实战(5.1) 字符和编码的基本概念

MySQL运维实战(5.1) 字符和编码的基本概念

字符和编码字符字符是符号,是人们用于交流的各类符号,如26个英文字母、汉字、标点符号、数学运算符、其他语言的字母和符号。编码编码是计算机中以二进制方式存储字符的方式。字符集字符集是字符和编码的映射表。...

MySQL运维实战(7.1) 开启GTID复制

MySQL从5.6版本开始支持GTID复制。开启GTID之后,主库上执行的每一个事务都有一个全局唯一的ID。GTID由两部分组成:server_uuid和事务序列号。初始化数据库时,会生成一个全局唯一...

MySQL优化器特性(三)表关联之BKA(Batched Key Access)优化

MySQL优化器特性(三)表关联之BKA(Batched Key Access)优化

单表range查询时,可以使用MRR优化,先对rowid进行排序,然后再回表查询数据。在表关联的时候,也可以使用类似的优化方法,先根据关联条件取出被关联表的rowid,将rowid缓存在join bu...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。