服务器SQL模式--记一次工作中遇到的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务器SQL模式--记一次工作中遇到的问题相关的知识,希望对你有一定的参考价值。

    在迁移一个老项目的时候碰到的问题。因为平时运行稳定,没什么问题,也太关注。这次迁移后测试,服务器报错:[Err] 1364 - Field ‘content‘ doesn‘t have a default value。

    觉得很奇怪,为什么会报这个错。之前运行一只很好的。无奈,根据逻辑找到这个相关表,给字段加上默认值,本以为可以测试通过,结果又有其它的字段报Field ‘xxxx‘ doesn‘t have a default value这个错误。检查数据表,发现好多表的字段设置不为空,但又没有给默认值,当时心里一个恨啊。但又觉得奇怪。为什么迁移服务器之前没有出现这种情况。查了好多问题,原来是开启了mysql的模式问题。

    

SELECT @@GLOBAL.sql_mode; 查询全局sql_mode   

SELECT @@SESSION.sql_mode; 查询当前会话sql_mode   

同样都出现了下面这个结果:

+--------------------------------------------+

| @@GLOBAL.sql_mode                          |

+--------------------------------------------+

| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |

+--------------------------------------------+

       

果然是开启了严格模式,那么通过设置model应该可以解决这个问题。   

SET GLOBAL sql_mode = ‘‘;

SET SESSION sql_mode = ‘‘;

    

重新测试,果然问题解决。果断的修改mysql的配置,重启服务。

    

那么下面就来说说mysql的模式


NO_ENGINE_SUBSTITUTION

默认的SQL模式。

当语句(如CREATE TABLE或ALTER TABLE)指定已禁用或未编译的存储引擎时,控制默认存储引擎的自动替换。

因为存储引擎在运行时可以被插入,所以不可用的引擎被以同样的方式处理:

在禁用NO_ENGINE_SUBSTITUTION的情况下,对于CREATE TABLE,将使用默认引擎,如果所需的引擎不可用,则会发生警告。 对于ALTER TABLE,会发生警告,并且表不会被更改。

如果启用了NO_ENGINE_SUBSTITUTION,则会发生错误,并且如果所需的引擎不可用,则不会创建或更改该表。


严格的SQL模式

- STRICT_ALL_TABLES

  为所有存储引擎启用严格的SQL模式。 无效的数据值被拒绝。 

- STRICT_TRANS_TABLES

  为事务性存储引擎启用严格的SQL模式,并在非事务性存储引擎可能的情况下启用。 


严格模式控制MySQL如何处理数据更改语句(如INSERT或UPDATE)中的无效或缺失值。 由于以下原因,值可能无效。 例如,该列可能具有错误的数据类型,或者可能超出范围。 如果要插入的新行没有包含定义中没有显式DEFAULT子句的非NULL列的值,则缺少一个值。 (对于NULL列,如果值缺失,则插入NULL。)严格模式也会影响DDL语句,如CREATE TABLE。


如果严格模式没有生效,MySQL将插入调整后的值作为无效值或缺失值,并产生警告。 在严格模式下,您可以使用INSERT IGNORE或UPDATE IGNORE来产生此行为。

对于不改变数据的SELECT等语句,无效值将在严格模式下生成警告,而不是错误。

从MySQL 5.6.11开始,严格模式会尝试创建超出最大密钥长度的密钥。 以前,这会导致警告并截断最大密钥长度的密钥(与严格模式未启用时相同)。

严格模式不会影响是否检查外键约束。 foreign_key_checks可以用于这个。

如果启用了STRICT_ALL_TABLES或STRICT_TRANS_TABLES,则严格的SQL模式有效,但这些模式的效果有所不同:

- 对于事务表,当启用STRICT_ALL_TABLES或STRICT_TRANS_TABLES时,数据更改语句中的无效值或缺失值会发生错误。 该声明被中止并回滚。

- 对于非事务性表,如果在要插入或更新的第一行中出现错误值,则对于任一模式,行为都是相同的:语句被中止,表保持不变。 如果语句插入或修改多行,并且第二行或更后一行出现错误值,则结果取决于启用了哪个严格模式:

  - 对于STRICT_ALL_TABLES,MySQL返回一个错误,并忽略其余的行。 但是,由于先前的行已被插入或更新,所以结果是部分更新。 为了避免这种情况,可以使用单行语句,可以在不更改表的情况下中止。

  - 对于STRICT_TRANS_TABLES,MySQL将无效值转换为列的最接近的有效值并插入调整后的值。 如果缺少一个值,MySQL将插入列数据类型的隐式默认值。 无论哪种情况,MySQL都会生成警告而不是错误,并继续处理语句。 (如查表字段设置不为空,而且没有给默认值,那么在执行insert语句的时候会报错[Err] 1364 - Field ‘content‘ doesn‘t have a default value)


严格模式还影响日期中由零,零日期和零处理除法,结合ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE和NO_ZERO_IN_DATE模式。 有关详细信息,请参阅这些模式的说明。


服务器SQL模式


MySQL服务器可以在不同的SQL模式下运行,并且可以根据sql_mode系统变量的值对不同的客户端应用不同的模式。 DBA可以设置全局SQL模式以匹配站点服务器操作需求,每个应用程序可以根据自己的需要设置其会话SQL模式。


模式会影响MySQL支持的SQL语法以及数据验证检查的效果。 这使得在不同的环境中使用MySQL变得更容易,并且可以将MySQL与其他数据库服务器一起使用。


在使用InnoDB表时,请考虑innodb_strict_mode系统变量。 它为InnoDB表启用额外的错误检查。


最重要的sql_mode值可能是这些:


- ANSI

  此模式更改语法和行为以更加符合标准SQL。 这是本节最后列出的特殊组合模式之一。

- STRICT_TRANS_TABLES

  如果某个值无法插入到事务表中,请中止该语句。 对于非事务性表,如果该值出现在单行语句或多行语句的第一行中,则中止该语句。 更多细节在本节后面给出。

  为事务性存储引擎启用严格的SQL模式,并在非事务性存储引擎可能的情况下启用。

- TRADITIONAL

  使MySQL像“传统”的SQL数据库系统一样行事。 在将不正确的值插入列时,此模式的简单描述是“给出错误而不是警告”。

  注意

  一旦发现错误,INSERT或UPDATE将立即中止。 如果您使用的是非事务性存储引擎,则这可能不是您想要的,因为在错误之前进行的数据更改可能无法回滚,从而导致“部分完成”更新。


需要查看更多模式,请查询mysql官方手册https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html




本文出自 “coding” 博客,请务必保留此出处http://xtceetg.blog.51cto.com/5086648/1981530

以上是关于服务器SQL模式--记一次工作中遇到的问题的主要内容,如果未能解决你的问题,请参考以下文章

记一次若依微服务版mybatis升级mybatis-plus之后遇到的坑

记一次使用mybatis进行like 模糊查询遇到的问题

优化器Bug?记一次慢SQL问题分析过程

记一次db2 备份恢复过程中遇到的用户权限问题

记一次项目中遇到的git问题

记一次曾经项目中遇到的错误