首页 > 数据库 >详细分析Mysql中的SQL_MODE基本知识

详细分析Mysql中的SQL_MODE基本知识

时间:2025-01-14 10:33:44浏览次数:1  
标签:NO -- SQL ZERO mode sql Mysql DATE MODE

 一、基础知识

sql_mode是MySQL中用于设置sql语法和行为的系统变量;

控制MySQL的sql解析和执行的方式,使其与sql标准或其他数据库系统的行为一致,通过设置sql_mode,可以改变MySQL处理待定sql操作的方式。

  • MySQL5.7

    默认sql_mode包括(7个):

      1)ONLY_FULL_GROUP_BY;
      2)STRICT_TRANS_TABLES;
      3)NO_ZERO_IN_DATE;
      4)NO_ZERO_DATE;
      5)ERROR_FOR_DIVISION_BY_ZERO;
      6)NO_AUTO_CREATE_USER;
      7)NO_ENGINE_SUBSTITUTION;

  • MySQL8.0

    默认sql_mode包括(6个):

      1)ONLY_FULL_GROUP_BY;
      2)STRICT_TRANS_TABLES;
      3)NO_ZERO_IN_DATE;
      4)NO_ZERO_DATE;
      5)ERROR_FOR_DIVISION_BY_ZERO;
      6)NO_ENGINE_SUBSTITUTION;

    需要自己配置的mode(4个):

      1)NO_AUTO_VALUE_ON_ZERO:该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。
      2)NO_AUTO_CREATE_USER:禁止GRANT创建密码为空的用户
      3)PIPES_AS_CONCAT:将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样是,也和字符串的拼接函数Concat想类似
      4)ANSI_QUOTES:不能用双引号来引用字符串,因为它被解释为识别符

  相比之下,MySql8.0默认mode没有太大的变化,但 NO_AUTO_CREATE_USER 被移除了,因为MySql8.0取消了自动创建用户的特性;

二、sql_mode的作用

  • sql_mode是一组语法校验规则

三、查询sql_mode

  • 执行sql查询
select @@GLOBAL.sql_mode

select @@SESSION.sql_mode
  • 查看my.conf配置文件(文件夹路径为)
C:\ProgramData\MySQL\MySQL Server 8.0

四、常见mode详细解释

4.1 ONLY_FULL_GROUP_BY

解释:对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中

4.2 STRICT_TRANS_TABLES

解释:如果一个值不能插入到一个事务中,则中断当前的操作,对非事务表不做限制;

在 STRICT_TRANS_TABLES 模式下,如果插入的数据有问题(如超出字段长度或类型不匹配),mysql会报错并回滚事务;

-- 设置 SQL_MODE 为 STRICT_TRANS_TABLES
SET sql_mode = 'STRICT_TRANS_TABLES';

-- 创建表
CREATE TABLE demo_strict (
    id INT,
    name VARCHAR(5)
);

-- 尝试插入超长数据
INSERT INTO demo_strict VALUES (1, 'TooLongName');

执行结果:

INSERT INTO demo_strict VALUES (1, 'TooLongName');
[Err] 1406 - Data too long for column 'name' at row 1

4.3 NO_ZERO_IN_DATE

解释:不允许日期和月份为零

4.4 NO_ZERO_DATE

解释:mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告

-- 设置 SQL_MODE 为 NO_ZERO_IN_DATE, NO_ZERO_DATE
SET sql_mode = 'NO_ZERO_IN_DATE,NO_ZERO_DATE';

-- 创建表
CREATE TABLE demo_date (
    id INT,
    date_field DATE
);

-- 尝试插入无效日期
INSERT INTO demo_date VALUES (1, '2020-00-00');

但在执行的过程中是可以成功的,但查询的时候日期显示未0000-00-00
为了避免这种插入无效日期,应该更改为:

-- 确保启用严格模式和日期模式
SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE';

-- 创建表
CREATE TABLE demo_date (
    id INT,
    date_field DATE
);

-- 尝试插入无效日期
INSERT INTO demo_date VALUES (1, '2020-00-00');

最终结果如下:

[Err] 1292 - Incorrect date value: '2020-00-00' for column 'date_field' at row 1

4.5 ERROR_FOR_DIVISION_BY_ZERO

解释:在insert或update过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时Mysql返回NULL

4.6 NO_ENGINE_SUBSTITUTION

解释:如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

-- 设置 SQL_MODE 为 NO_ENGINE_SUBSTITUTION
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';

-- 尝试创建不存在的存储引擎的表
CREATE TABLE demo_engine (
    id INT
) ENGINE=NON_EXISTENT_ENGINE;

报错结果如下:[Err] 1286 - Unknown storage engine 'NON_EXISTENT_ENGINE'

4.7 NO_AUTO_VALUE_ON_ZERO

解释:该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。

4.8 NO_AUTO_CREATE_USER

解释:禁止GRANT创建密码为空的用户

4.9 PIPES_AS_CONCAT

解释:将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样是,也和字符串的拼接函数Concat想类似

4.10 ANSI_QUOTES

解释:不能用双引号来引用字符串,因为它被解释为识别符;双引号用于标识符,而不是字符串

-- 设置 SQL_MODE 为 ANSI_QUOTES
SET sql_mode = 'ANSI_QUOTES';

-- 尝试使用双引号作为标识符
CREATE TABLE "demo_quotes" (
    "id" INT,
    "name" VARCHAR(50)
);

-- 插入数据
INSERT INTO "demo_quotes" ("id", "name") VALUES (1, 'John Doe');

成功插入;

五、设置sql_mode(一旦设置了,就不会再用默认配置的mode规则)

5.1 命令行设置(两个都可以),重启失效

SET GLOBAL SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

5.2 配置文件设置

  • 加下面这行,按需添加mode(作者只是举例)
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

 

原文链接:https://blog.csdn.net/weixin_47872288/article/details/139392961
     https://blog.csdn.net/m0_46085118/article/details/132737981

标签:NO,--,SQL,ZERO,mode,sql,Mysql,DATE,MODE
From: https://www.cnblogs.com/daytoy105/p/18670143

相关文章

  • MySQL之DDL语言
    目录一、数据库的基本操作1、创建数据库语法:示例:2、修改数据库语法:示例:3、删除数据库语法:示例:4、查询数据库语法:5、使用数据库语法:二、数据表的基本操作1、创建数据表语法:示例:2、重命名数据表语法:示例:3、删除数据表语法:示例:4、查询数据表语法:三、表......
  • 3分钟搞懂Arrow Flight SQL,让数据传输提速100倍的秘密
    3分钟搞懂ArrowFlightSQL,让数据传输提速100倍的秘密数据传输提速100倍!如何做到100倍提升?让数据传输起飞!小结此时,数据分析师小华揉着发酸的眼睛,望着电脑屏幕发呆。他忍不住抱怨道:“这数据导出也太慢了吧!”是的,又一次等待MySQL协议传输大批量数据,这感觉像是用吸管......
  • SQL刷题快速入门(二)
    其他章节:SQL刷题快速入门(一)承接上一章节,本章主要讲SQL的运算符、聚合函数、SQL保留小数的几种方式三个部分运算符SQL支持多种运算符,用于执行各种操作,如算术运算、比较、赋值、逻辑运算等。以下是一些常见的SQL运算符类型及其示例:算术运算符+(加)-(减)*(乘)/(除)%(取模)SELECT......
  • MySQL(高级特性篇) 03 章——用户与权限管理
    一、用户管理MySQL用户可以分为普通用户和root用户。root用户是超级管理员,拥有所有权限,包括创建用户、删除用户和修改用户的密码等管理权限。普通用户只拥有被授予的各种权限MySQL提供了许多语句用来管理用户账号,这些语句可以用来管理包括登录和退出MySQL服务器、创建用户、......
  • sql中的表的关联有哪几种类型?
    sql中的join示例:测试数据准备:createtabletest_student(s_idstring,s_namestring,s_ageint);insertintotest_studentvalues('s1','张三',15);insertintotest_studentvalues('s2','李四',16);insertintotest_studentva......
  • java项目之教师工作量管理系统(ssm+mybatis+mysql)
    风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的码农一枚。今天要和大家聊的是一款基于ssm的教师工作量管理系统。项目源码以及部署相关请联系风歌,文末附上联系信息。项目简介:教师工作量管理系统的主要使用者管理员可以管理教师,可以对教师信息修改删除以及查询操作;可以查......
  • mysql、oracle、sqlserver的区别
    一、保存数据的持久性:        MySQL:是在数据库更新或者重启,则会丢失数据。                Oracle:把提交的sql操作线写入了在线联机日志文件中,保持到了磁盘上,可以随时恢复。                SqlServer:2014之后,也拥有了完全持久和延......
  • MySQL中的四种表联结
    目录1、联结、关系表(1)关系表(2)为什么使用联结2、如何创建联结(1)笛卡尔积(叉联结)--用逗号分隔(2)where子句的重要性(3)内联结--INNERJOIN (4)联结多个表3、使用表别名(对比列别名)4、自联结、自然联结、外联结(1)自联结:self-join(2)自然联结:naturaljoin(3)外联结:leftjoin、righ......
  • Oracle SQL每日一问之ORA-01723:zero-length columns are not allowed
    我:CREATETABLETABLE_1PARALLEL8ASSELECT/*+parallel(8)*/t1.emp_no,NULLemp_nameFROMtemp1t1;[AI机器人bot:]在你的SQL语句中,错误"zero-lengthcolumnsarenotallowed"可能是由于在创建表时没有为`NULLclct_flag`指定数据类型。即使在`CREATETAB......
  • JAVA开源毕业设计 共享汽车管理系统 Vue.JS+SpringBoot+MySQL
    本文项目编号T125,文末自助获取源码\color{red}{T125,文末自助获取源码}......