2023-05-10 08:00:02

禁用ONLY_FUL_GROUP_BY

我意外启用了ONLY_FUL_GROUP_BY模式,如下所示:

SET sql_mode = 'ONLY_FULL_GROUP_BY';

如何禁用它?


当前回答

仅向sql_mode添加一种模式,而不删除现有模式:

SET sql_mode=(SELECT CONCAT(@@sql_mode,',<mode_to_add>'));

仅从sql_mode中删除特定模式,而不删除其他模式:

SET sql_mode=(SELECT REPLACE(@@sql_mode,'<mode_to_remove>',''));

在这种情况下,如果您只想删除only_FUL_GROUP_BY模式,请使用以下命令:

SET sql_mode=(SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));

参考:http://johnemb.blogspot.com/2014/09/adding-or-removing-individual-sql-modes.html

其他回答

我注意到@Eyo-Okon-Eyo解决方案只要MySQL服务器没有重启,默认设置就会恢复。这里有一个对我有效的永久解决方案:

要删除特定的SQL模式(在本例中为ONLY_FUL_GROUP_BY),请查找当前的SQL模式:

SELECT @@GLOBAL.sql_mode;

复制结果并从中删除不需要的内容(ONLY_FUL_GROUP_BY)

例如。:

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

to

STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

创建并打开此文件:

/etc/mysql/conf.d/disable_strict_mode.cnf

并将新的SQL模式写入其中:

[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

重新启动MySQL:

sudo service mysql restart

或者您可以使用ANY_VALUE()抑制ONLY_FUL_GROUP_BY值拒绝,您可以在这里阅读更多信息

感谢@cwhisperer。我在Symfony应用程序中也遇到了同样的问题。我刚刚在config.yml中添加了选项:

doctrine:
    dbal:
        driver:   pdo_mysql
        options:
            # PDO::MYSQL_ATTR_INIT_COMMAND
            1002: "SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))"

这对我来说很好。

如果sql_mode上有ANSI,需要注意一点:

等效于REAL_AS_FLOAT、PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE和(从MySQL 5.7.5开始)ONLY_FUL_GROUP_BY。

看见https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_ansi

向sql_mode添加或删除模式

MySQL 5.7.9或更高版本

要在sql_mode中添加或删除模式,可以使用list_add和list_drop函数。

要从当前SESSION.sql_mode中删除模式,可以使用以下方法之一:

SET SESSION sql_mode = sys.list_drop(@@SESSION.sql_mode, 'ONLY_FULL_GROUP_BY');
SET sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY');
SET @@sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY');

从GLOBAL.sql_mode中删除当前运行时操作持续的模式,直到服务重新启动。

SET GLOBAL sql_mode = sys.list_drop(@@GLOBAL.sql_mode, 'ONLY_FULL_GROUP_BY');

MySQL 5.7.8或更高版本

由于sql_mode值是一个CSV模式字符串,因此您需要确保该字符串不包含残留逗号,这可以通过使用TRIM(BOTH','FROM…)来实现。

要从sql_mode变量中删除模式,您需要使用REPLACE()和TRIM()来确保删除任何残留的逗号。

SET SESSION sql_mode = TRIM(BOTH ',' FROM REPLACE(@@SESSION.sql_mode, 'ONLY_FULL_GROUP_BY', ''));
SET GLOBAL sql_mode = TRIM(BOTH ',' FROM REPLACE(@@GLOBAL.sql_mode, 'ONLY_FULL_GROUP_BY', ''));

要将模式添加到sql_mode变量,您需要使用CONCAT_WS(',',…)来确保在当前模式后面附加逗号,并使用TRIM()来确保删除任何剩余的逗号。

SET SESSION sql_mode = TRIM(BOTH ',' FROM CONCAT_WS(',', 'ONLY_FULL_GROUP_BY', @@SESSION.sql_mode));
SET GLOBAL sql_mode = TRIM(BOTH ',' FROM CONCAT_WS(',', 'ONLY_FULL_GROUP_BY', @@GLOBAL.sql_mode));

注意:在建立新连接之前,更改GLOBAL变量不会传播到SESSION变量。GLOBAL变量将持续存在,直到正在运行的服务重新启动。SESSION变量将持续用于当前连接,直到连接关闭并建立新连接。


还原为GLOBAL.sql_mode

由于SET sql_mode='ONLY_FUL_GROUP_BY';在没有GLOBAL修饰符的情况下执行时,更改仅影响当前SESSION状态值,该值也属于@@sql_mode。要删除它并恢复到服务器重启时的全局默认值,您需要使用@@global.sql_mode中的值。[sic]

当前SESSION值仅对当前连接有效。重新连接到服务器将将值还原回GLOBAL价值

要将当前会话状态值还原为当前全局值,可以使用以下方法之一:

SET SESSION sql_mode = @@GLOBAL.sql_mode;
SET @@sql_mode = @@GLOBAL.sql_mode;
SET sql_mode = @@GLOBAL.sql_mode;

将SESSION.sql_mode值更改为ONLY_FUL_GROUP_BY

SET sql_mode = 'ONLY_FULL_GROUP_BY';
SELECT @@sql_mode, @@GLOBAL.sql_mode;
+--------------------+----------------------------------------------+
| @@sql_mode         | @@GLOBAL.sql_mode                            |
+--------------------+----------------------------------------------+
| ONLY_FULL_GROUP_BY | NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION |
+--------------------+----------------------------------------------+

将SESSION.sql_mode值还原为GLOBAL.sql_mde值

SET sql_mode = @@GLOBAL.sql_mode;
SELECT @@sql_mode, @@GLOBAL.sql_mode;
+----------------------------------------------+----------------------------------------------+
| @@sql_mode                                   | @@GLOBAL.sql_mode                            |
+----------------------------------------------+----------------------------------------------+
| NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION | NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION |
+----------------------------------------------+----------------------------------------------+

使用选项文件重新启动服务器持久sql_mode

设置SQL模式在服务器启动时,在命令上使用--sqlmode=“modes”选项行或sql mode=“modes”(在选项文件中,如my.cnf(Unix操作系统)或my.ini(Windows)。[原文]

请查看您的MySQL版本,以确定支持的模式和默认模式。

MySQL>=5.7.5,<=5.7.6默认值

[mysqld]
    
sql-mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"

有关详细信息,请参阅选项文件语法。

在选项文件中指定选项的语法类似于命令行语法。但是,在选项文件中,可以省略前导选项名称中的两个破折号,每个选项只能指定一个选项线例如,命令行上的--quick和--host=localhost应在选项文件。要在中指定格式为--loose-opt_name的选项一个选项文件,将其写为loose-opt_name。

该值可选地可以用单引号括起来,或者双引号,如果值包含#注释字符。

默认sql_mode值

由于删除了每个版本的MySQL文档值,我将它们添加到这里供您参考。

MySQL 8.0[sic]MySQL 5.7[sic]MySQL 5.6[sic]

MySQL>=8.0.11 8.0.5-8.0.10已跳过

ONLY_FULL_GROUP_BY STRICT_TRANS_TABLES NO_ZERO_IN_DATE NO_ZERO_DATE ERROR_FOR_DIVISION_BY_ZERO NO_ENGINE_SUBSTITUTION

MySQL>=5.7.8,<=8.0.4

ONLY_FULL_GROUP_BY STRICT_TRANS_TABLES NO_ZERO_IN_DATE NO_ZERO_DATE ERROR_FOR_DIVISION_BY_ZERO NO_AUTO_CREATE_USER NO_ENGINE_SUBSTITUTION

MySQL 5.7.7

ONLY_FULL_GROUP_BY STRICT_TRANS_TABLES NO_AUTO_CREATE_USER NO_ENGINE_SUBSTITUTION

MySQL>=5.7.5,<=5.7.6

ONLY_FULL_GROUP_BY STRICT_TRANS_TABLES NO_ENGINE_SUBSTITUTION

MySQL>=5.6.6,<=5.7.4

NO_ENGINE_SUBSTITUTION

MySQL<=5.6.5

''

对于MySql 8,您可以尝试这个。(未在5.7中进行测试。希望它在那里也适用)

首先打开此文件

sudo vi/etc/mysql/my.cnf并将以下代码粘贴在上述文件的末尾

[mysqld]
sql_mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

然后通过运行这个sudo服务mysql restart重新启动mysql