关于laravel解决mysql only_full_group_by问题
下面由Laravel教程栏目给大家介绍laravel解决mysql only_full_group_by问题的方法,希望对需要的朋友有所帮助!
MySQL 5.7 之后 only_full_group_by 默认是开启的,这就导致 sql 的检测更加严格,将导致报下面的错
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'edu.t_sounds.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
解决这个问题也走了不少弯路,按照网上找的方式一个一个试
解决思路
查看 sql_mode
select @@GLOBAL.sql_mode;SELECT @@SESSION.sql_mode
首先查看并修改 mysql 配置文件,my.cnf 很尴尬我的这个里面并没有 ONLY_FULL_GROUP_BY
[mysqld]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
不行,就接着来,想到mysql 有服务端配置,和客户端配置之分,那就增加 [client] 配置
[client]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
重启mysql ,在MySQL工具查看 sql_mode,确实显示结果和配置的是一样的,但是程序依然报同样的错
又是一番查找,突然意识到 global session 的问题,也就是文章头部放的两条查询 sql_mode 的语句,就查询一下 是啥区别
mysql 变量设置方式分两种,
一种全局配置,也就是 global,作用于全局;
一种会话配置 session, 只作用于当前连接
会不会是laravel 在当前连接设置了 sql_mode
在 laravel 程序打印 sql_mode
$result = \DB::select('SELECT @@GLOBAL.sql_mode'); print_r($result);exit; 结果: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION $result = \DB::select('SELECT @@SESSION.sql_mode'); print_r($result);exit; 结果: 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 的配置有一个严格模式,我一直是开启状态,设置为 false 问题顺利解决
'strict' => false,
- 这样可以解决问题,但本着技术就是要搞清楚到底是咋写的,也并不想直接给他设置为 false,
在 vendor/laravel/framework/src/ILLuminate/Database 文件夹下搜索 strict ,直接找到核心代码
文件:vendor/laravel/framework/src/ILLuminate/Database/Connectors/MySqlConnector.php
protected function setModes(PDO $connection, array $config){ if (isset($config['modes'])) { $this->setCustomModes($connection, $config); } elseif (isset($config['strict'])) { if ($config['strict']) { $connection->prepare($this->strictMode($connection))->execute(); } else { $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute(); } }}
第一个判断直接判断是否存在 modes 配置,有的话就直接使用这个
来,搞一下
'modes' => ['STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_pISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION'],
测试,直接问题搞定
本着寻根刨底的精神,再接着往下看
如果 strict = true
将直接设置程序中写死的 sql_mode, laravel 区分了 mysql 8.0.11 和别的版本
protected function strictMode(PDO $connection) { if (version_compare($connection->getAttribute(PDO::ATTR_SERVER_VERSION), '8.0.11') >= 0) { return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'"; } return "set session sql_mode='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'"; }
再接着 如果 strict = false ,直接将 sql_mode 设置为NO_ENGINE_SUBSTITUTION
$connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
到这里问题就彻底解决了
最终解决方式
'strict' => true, 'modes' => ['STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION'],
保留了 strict = true,增加 modes 选项,里面的参数是 laravel 底层的配置,只是去掉了 ONLY_FULL_GROUP_BY
总结:走了不少弯路,也花了不少时间,最终问题解决,并且并不需要修改 mysql 的任何配置
Atas ialah kandungan terperinci 关于laravel解决mysql only_full_group_by问题. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas





Kaedah untuk mendapatkan kod kembali apabila menghantar e -mel Laravel gagal. Apabila menggunakan Laravel untuk membangunkan aplikasi, anda sering menghadapi situasi di mana anda perlu menghantar kod pengesahan. Dan pada hakikatnya ...

Tugas Jadual Laravel menjalankan penyelesaian masalah yang tidak responsif semasa menggunakan penjadualan tugas jadual Laravel, banyak pemaju akan menghadapi masalah ini: Jadual: Jalankan ...

Kaedah mengendalikan kegagalan e -mel Laravel untuk menghantar kod pengesahan adalah menggunakan Laravel ...

Cara melaksanakan fungsi jadual klik tersuai untuk menambah data dalam dcatadmin (laravel-admin) semasa menggunakan dcat ...

Laravel - Dump Server - Laravel dump server datang dengan versi Laravel 5.7. Versi sebelumnya tidak termasuk pelayan dump. Pelayan dump akan menjadi kebergantungan pembangunan dalam fail komposer laravel/laravel.

Kesan perkongsian sambungan Redis dalam rangka kerja Laravel dan pilih kaedah apabila menggunakan Rangka Kerja Laravel dan Redis, pemaju mungkin menghadapi masalah: melalui konfigurasi ...

Sambungan pangkalan data penyewa tersuai dalam pakej lanjutan multi-penyewa Larave Stancl/penyewaan ketika membina aplikasi multi-penyewa menggunakan pakej lanjutan multi-penyewa Larave Stancl/penyewaan, ...

Laravel - URL Tindakan - Laravel 5.7 memperkenalkan ciri baharu yang dipanggil "URL tindakan boleh panggil". Ciri ini serupa dengan yang terdapat dalam Laravel 5.6 yang menerima kaedah rentetan dalam tindakan. Tujuan utama sintaks baharu memperkenalkan Laravel 5.7 adalah untuk mengarahkanl
