php - SQL_MODE 不适用于 MySQL 5.7.18

标签 php mysql ubuntu apache2 sql-mode

我的 PHP 应用程序出现以下错误:

Incorrect SQL query (Database) In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'db_20172201.cm_order.buyer'; this is incompatible with sql_mode=only_full_group_by

环顾了一段时间,并尝试找出导致此错误的查询后,我决定更改 MySQL 服务器中的 SQL_MODE 选项。

我做了两件事来实现这一目标:

  • 执行了此查询

    SET SESSION 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 的配置文件 my.cnf 中添加了以下内容

    [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"
    

我认为这些就足够了,但错误永远不会从我的应用程序中消失。 当我通过此查询检查环境中 SQL_MODE 的值时

SELECT @@GLOBAL.sql_mode

它显示上面插入的值。

我不知道还能去哪里看。我还尝试在执行查询之前从应用程序设置 sql_mode 变量,但没有解决。

--- 更新

我刚刚在我的应用程序中打印了查询 SELECT @@SESSION.SQL_MODE 的结果,结果与我设置的一样:

array(1) { [0]=> object(stdClass)#5 (1) 
    { 
        ["@@SESSION.sql_mode"] => string(118) "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
    }
}

但我仍然收到错误

PS。 MySQL版本是5.7.18

最佳答案

存储程序(过程、函数、触发器和事件)具有一些许多用户从未注意到的特殊机制,因为它们通常“正常工作”。

创建存储程序时,环境的某些方面将被捕获并与代码一起存储,并在每次调用程序时使用。

SHOW CREATE PROCEDURE ...向您展示这些值。

其中之一是@@SQL_MODE

这允许过程的定义者确保过程运行时的环境始终具有这些属性。

那么,官方的答案是删除并在正确的环境中重新创建过程。

但是...这里的属性实际上存储在mysql.proc表中。因此,只要您牢记以下几点,您就有一个潜在的“快速解决方案”:

The server manipulates the mysql.proc table in response to statements that create, alter, or drop stored routines. It is not supported that the server will notice manual manipulation of this table.

https://dev.mysql.com/doc/refman/5.7/en/stored-routines-privileges.html

如果该系统并不重要并且您有备份,则可以仔细操作 mysql.proc 表行以更改 sql_mode,然后重新启动 MySQL 服务器进程,以便考虑对表的更改。

请注意,另一个看似可行的选项 - 使用 mysqldump 创建转储文件并重新加载它 - 将不会产生任何效果,因为 mysqldump 将语句添加到转储文件中确保使用创建转储文件时过程中存在的相同设置来恢复过程 - 因此对全局服务器配置的更改将不起作用。

您当然可以修改转储文件来更改这些值,但这是一个有点高级的操作。

如果您从包含 SQL 语句但未显式设置 sql_mode 的文件加载此架构,则重新加载该文件也应该具有所需的效果。

最后,请注意,ONLY_FULL_GROUP_BY 试图保护您免受使用 MySQL 分组扩展的查询的影响,其方式与该功能的目的不一致。从 5.7.x 开始,被 ONLY_FULL_GROUP_BY 拒绝的查询实际上可能会产生不确定的结果,或者可能利用意外或巧合正确的副作用或结果 - 而不是根据设计,这种行为可能会在未来的版本中消失(例如,由于查询优化器的更改),因此不应依赖。

最好的解决方案是使查询在理论上正确。

关于php - SQL_MODE 不适用于 MySQL 5.7.18,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44169392/

相关文章:

php - 如何避免硬编码数据库连接密码?

php - 检测 MySQL 数据库中更新的行是否已更改

php - 如何检查mysql的哪一个结果在线重定向

php - 在 PHP 中使用对 MySQL 的单个 mysqli_fetch_array() 查询填充多个下拉列表

JAVA_HOME 未正确定义。乌类图

mysql - 修复 Docker 中的 World-writable MySql 错误

MYSQL:同一张表上的两个连接变成双分组计数。如何解决?

mysql - 无法触发运行

python - Ubuntu 9.10 中奇怪的 pynotify 行为

ubuntu - 在 Ubuntu+Nginx+Tomcat 中部署 Geoserver 的问题