mysql的sql_mode

本文深入探讨了MySQL中SQL模式的设置方法、模式说明及应用案例,包括如何通过设置不同的SQL模式来解决数据校验问题,确保数据准确性和兼容性。通过实例展示了ANSI、STRICT_TRANS_TABLES和TRADITIONAL模式的使用场景与效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


mysql可以运行在不同sql mode模式下面,sql mode模式定义了mysql应该支持的sql语法,数据校验等! 
一、设置方法:

[mysqld] --下添加如下设置

transaction-isolation=SERIALIZABLE
sql-mode=ANSI

二、模式说明:
查看默认的sql mode模式: 
select @@sql_mode; 
我的数据库是: 
STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 
在此模式下面,如果插入的数据的长度大于定义的长度,那么就会报错! 

默认情况下是空。
  
set session sql_mode='REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI'; 
在这种模式下面:插入的数据的长度大于定义的时候,就会截取,并警告,但是可以插入进去 
session表示只在本次中有效 
global:表示在本次连接中不生效,而对于新的连接就生效 
  
启用NO_BACKSLASH_ESCAPES模式,使反斜线成为普通字符,在导入数据时候,如果数据中有反斜线,启用这个模式是个不错的选择 
  
启用PIPES_AS_CNCAT模式,将||看成是普通字符串 
  
常用的sql mode: 
sql mode值 说明
ANSI:       'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE和ANSI组合',这种模式使语法和行为更符合标准的sql 
STRICT_TRANS_TABLES : 使用与事务和非事务表,严格模式 
TRADITIONAL : 也是严格模式,对于插入不正确的值给出错误而不是警告。用在事务时,只要发生错误就立即回滚

在Mysql5.0以下,默认的 (sql mode参数)有:real_as_float,pipes_as_concat,ansi_quotes,gnore_space和ANSI。在这些模式下可以插入超过字段定义长度的数据,或是在字段中没有定义的元素数据(如,enum)。不过在插入后会有一个warning(可以用 show warnings来查看)。 在Mysql5.0以上版本中,有三种sql mode模式(ANSI、TRADITIONAL和STRICT_TRANS_TABLES(严格模式))可以用来解决以下问题:
(1). 通过设置不同的sql mode,可以在不同严格程序进行数据校验,有效地保证了数据准确性.
(2).通过设置sql mode为ANSI模式,来保证大多数SQL符合标准SQL的语法,这样在不同数据库之间迁移时,不需要对业务修改太多.通过设置sql mode为STRICT_TRANS_TABLES(严格模式)来实现数据的严格校检,使错误数据不能插入,从而保证数据准确性。TRADITIONAL模式也属于严格模式,同样可以实现严格校检,使错误数据不能插入,从而保证数据准确性。不过在这种模式MAX(X,0)返回的结果是NULL,所以在包含有MAX的运算中根据实际情况设定好sql mode.ENUM是一个字符串对象,其值来自表创建时在列规定中显式枚举的一列值。在某些情况下,ENUM值也可以为空字符串('')或NULL:如果你将一个非法值插入ENUM(也就是说,允许的值列之外的字符串),将插入空字符串以作为特殊错误值。该字符串与“普通”空字符串不同,该字符串有数值值0。
如果将ENUM列声明为允许NULL,NULL值则为该列的一个有效值,并且 默认值为NULL。如果ENUM列被声明为NOT NULL,其默认值为允许的值列的第1个元素。
(1)sql mode为ANSI
mysql> create table test(id bigint(20) auto_increment primary key, browsertype enum('ie','firefox','other'));
mysql> insert into test(browsertype) values('ie') ;
Query OK, 1 row affected (0.07 sec) 
mysql> insert into test(browsertype) values('maxthon') ;
Query OK, 1 row affected (0.03 sec) 
mysql> show warnings;(数据虽然成功insert,但有warning)
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning | 1265 | Data truncated for column 'browsertype' at row 1 |
+---------+------+--------------------------------------------------+
1 row in set (0.01 sec)mysql> select * from test;
+----+-------------+
| id | browsertype |
+----+-------------+
| 1 | ie          |
| 2 |             |
+----+-------------+
2 rows in set (0.01 sec)(2)使用严格模式(STRICT_TRANS_TABLES)
mysql> set session sql_mode='STRICT_TRANS_TABLES';
Query OK, 0 rows affected (0.00 sec) 
mysql> select @@sql_mode;
+---------------------+
| @@sql_mode          |
+---------------------+
| STRICT_TRANS_TABLES |
+---------------------+
1 row in set (0.00 sec)
mysql> insert into test(browsertype) values('maxthon') ;
ERROR 1265: Data truncated for column 'browsertype' at row 1
mysql> insert into test(browsertype) values('firefox') ;
Query OK, 1 row affected (0.00 sec) mysql> select * from test;
+----+-------------+
| id | browsertype |
+----+-------------+
| 1 | ie          |
| 2 |             |
|   3 | firefox     |
+----+-------------+
3 rows in set (0.00 sec)
(3) TRADITIONAL模式
mysql> create table t11 (i int);
Query OK, 0 rows affected (0.02 sec) 
mysql> set sql_mode='ANSI';
Query OK, 0 rows affected (0.00 sec) 
mysql> insert into t11 values(9%0);
Query OK, 1 row affected (0.00 sec) 
mysql> select * from t11;
+------+
| i        |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
mysql> set sql_mode='TRADITIONAL';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t11 values(9%0);
ERROR 1365: Division by 0
mysql> show warnings;
+-------+------+---------------+
| Level | Code | Message       |
+-------+------+---------------+
| Error | 1365 | Division by 0 |
+-------+------+---------------+
1 row in set (0.02 sec)
<think>好的,我需要解决用户在Docker中运行的MySQL遇到的sql_mode包含only_full_group_by导致的问题。首先,我得回忆一下MySQLsql_mode的作用,特别是only_full_group_by模式的影响。这个模式要求GROUP BY子句必须包含所有非聚合列,否则会报错。用户可能是在执行某些查询时遇到了错误,需要修改或禁用这个配置。 接下来,用户使用的是Docker环境,所以需要找到如何在Docker容器中修改MySQL配置的方法。通常,MySQL的配置文件是my.cnf,位于/etc/mysql目录下。在Docker中,可以通过挂载自定义的配置文件到容器内的对应位置来覆盖默认配置。 然后,考虑如何具体修改sql_mode。用户可能想完全移除only_full_group_by,或者调整其他模式。需要给出修改my.cnf的示例,比如在[mysqld]部分设置sql_mode为其他值,比如STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION。同时,要提醒用户修改后重启MySQL服务或者整个容器才能使配置生效。 另外,用户可能不想修改配置文件,而是临时在运行时修改sql_mode。这时候可以通过进入容器执行SQL命令来动态调整,但要注意这种修改在容器重启后会失效。需要提供相应的命令示例,比如SET GLOBAL sql_mode = '...';,并说明这种方法的临时性。 还要考虑用户可能使用的Docker运行命令是否正确挂载了配置文件,比如使用-v参数将宿主机的配置文件目录挂载到容器的/etc/mysql/conf.d。需要检查用户是否已经正确设置了挂载点,或者是否需要创建自定义的配置文件。 另外,可能需要验证配置是否生效,比如进入容器查看sql_mode的当前值,或者执行查询测试是否还会报错。提供相应的检查步骤,比如执行SELECT @@GLOBAL.sql_mode;命令。 最后,需要确保引用的参考资料相关,虽然用户提供的引用似乎和MySQL或Docker关系不大,但可能涉及配置文件的处理方式,可以适当关联。例如,引用中提到配置用户组提供程序,可能与配置文件修改有关联,但需要谨慎引用,避免误导用户。 总结步骤应该是:修改配置文件、挂载到容器、重启服务、验证配置。同时提供临时方法和持久化方法的区别,确保用户理解不同方案的适用场景。</think>### Docker中MySQL禁用only_full_group_by配置解决方案 在Docker容器中运行的MySQL如果启用了$sql_mode=ONLY_FULL_GROUP_BY$,会导致包含非聚合列的GROUP BY查询报错。以下是两种主要解决方法: #### 方法一:修改配置文件(推荐) 1. **创建自定义配置文件** 新建文件$mysql-custom.cnf$,内容为: ```ini [mysqld] sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION ``` 2. **启动容器时挂载配置文件** ```bash docker run -d \ --name mysql8 \ -v /path/to/mysql-custom.cnf:/etc/mysql/conf.d/mysql-custom.cnf \ -e MYSQL_ROOT_PASSWORD=your_password \ mysql:8.0 ``` 3. **验证配置** ```bash docker exec -it mysql8 mysql -uroot -p SELECT @@GLOBAL.sql_mode; ``` #### 方法二:运行时动态修改(临时) ```sql -- 进入MySQL命令行 SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); ``` > 注意:该方法在容器重启后失效,需结合方法一实现持久化[^1] #### 配置原理说明 MySQL的$sql_mode$参数控制SQL语法校验严格程度,$ONLY_FULL_GROUP_BY$是SQL标准中GROUP BY子句的严格模式。通过修改配置文件可以永久改变服务端配置,而动态修改只影响当前会话[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值