zoukankan      html  css  js  c++  java
  • Mysql sql_mode设置 timestamp default 0000-00-00 00:00:00 创建表失败处理

    往数据库里创建新表的时候报错:

    [Err] 1067 - Invalid default value for 'updateTime'
    
    DROP TABLE IF EXISTS `passwd_reset`;
    CREATE TABLE `passwd_reset` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `staffId` int(11) DEFAULT NULL,
      `toEmail` varchar(50) DEFAULT NULL,
      `token` varchar(100) DEFAULT NULL,
      `validTime` int(11) DEFAULT NULL,
      `createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `updateTime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gbk;

    mysql5.7默认为

    sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
    改为

    sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    这样之前插入语句就能正常执行了

    sql_mode 常用值说明
    官方手册专门有一节介绍 https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html 。 SQL Mode 定义了两个方面:MySQL应支持的SQL语法,以及应该在数据上执行何种确认检查。

    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开始也默认了。

    数据检查类

    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出现少值或无效值该如何处理:
    1.把 ‘’ 传给int,严格模式下非法,若启用非严格模式则变成0,产生一个warning
    2.Out Of Range,变成插入最大边界值
    3.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

    上面并没有囊括所有的 SQL Mode,选了几个代表性的。
    sql_mode一般来说很少去关注它,没有遇到实际问题之前不会去启停上面的条目。我们常设置的 sql_mode 是 ANSI、STRICT_TRANS_TABLES、TRADITIONAL,ansi和traditional是上面的几种组合。
    ANSI:更改语法和行为,使其更符合标准SQL
    相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
    TRADITIONAL:更像传统SQL数据库系统,该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。
    相当于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
    ORACLE:相当于 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USE 无论何种mode,产生error之后就意味着单条sql执行失败,对于支持事务的表,则导致当前事务回滚;但如果没有放在事务中执行,或者不支持事务的存储引擎表,则可能导致数据不一致。MySQL认为,相比直接报错终止,数据不一致问题更严重。于是 STRICT_TRANS_TABLES 对非事务表依然尽可能的让写入继续,比如给个”最合理”的默认值或截断。而对于 STRICT_ALL_TABLES,如果是单条更新,则不影响,但如果更新的是多条,第一条成功,后面失败则会出现部分更新。
    5.6.6 以后版本默认就是NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,5.5默认为 ‘’ 。
    设置 sql_mode
    查看

    查看当前连接会话的sql模式:
    mysql> select @@session.sql_mode;
    或者从环境变量里取
    mysql> show variables like "sql_mode";
    查看全局sql_mode设置:
    mysql> select @@global.sql_mode;
    只设置global,需要重新连接进来才会生效
    设置

    mysql> set sql_mode='';
    mysql> set global sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';
    如果是自定义的模式组合,可以像下面这样
    Adding only one mode to sql_mode without removing existing ones:
    mysql> SET sql_mode=(SELECT CONCAT(@@sql_mode,','));
    Removing only a specific mode from sql_mode without removing others:
    mysql> SET sql_mode=(SELECT REPLACE(@@sql_mode,'',''));
    配置文件里面设置

    sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

    把sql_mode修改好之后,可以正常执行脚本。

    二. sql文件中timestamp为什么去掉了default current_timestamp?

    发现在新版的sql文件中所有的timestamp字段都去掉了default current_timestamp

    在MySQL 5.7版本建表提示出错,因为MySQL 5.7 SQL_MOD默认是strict

    https://stackoverflow.com/questions/9192027/invalid-default-value-for-create-date-timestamp-field

    原因:太多低于5.7版本的人反馈报错就去掉了


    三.  Mysql 5.7 timestamp

    • Mysql 5.7 timestamp 创建时必须设置每个时间戳类型的默认值,否则报错Error : Invalid default value for 'start_time'
    • 之前版本 默认第一个时间戳字段为defult current_timestamp,且只能设置一个默认为当前时间


    链接:https://www.jianshu.com/p/75f06beca977

    原文:https://blog.csdn.net/achuo/article/details/54618990

  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/lxwphp/p/11247181.html
Copyright © 2011-2022 走看看