Maison > cadre php > Laravel > le corps du texte

À propos de Laravel résolvant le problème MySQL only_full_group_by

藏色散人
Libérer: 2021-01-26 09:10:55
avant
3006 Les gens l'ont consulté
Vous trouverez ci-dessous

Tutoriel Laravel colonne pour présenter la méthode de résolution de MySQL par Laravel only_full_group_by. J'espère que cela sera utile aux amis qui en ont besoin !

Après MySQL 5.7, only_full_group_by est activé par défaut, ce qui conduit à une détection SQL plus stricte, ce qui entraînera le signalement de l'erreur suivante

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
Copier après la connexion
Il n'y a aucun moyen pour résoudre ce problème. Évitez les détours et essayez un par un selon les méthodes trouvées en ligne

Idées de solutions

Voir sql_mode

select @@GLOBAL.sql_mode;SELECT @@SESSION.sql_mode
Copier après la connexion

Vérifiez et modifiez d'abord le fichier de configuration mysql. My.cnf est très embarrassant. Il n'y a pas de ONLY_FULL_GROUP_BY dans my.cnf. Selon la configuration du client, ajoutez la configuration [client]
[mysqld]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
Copier après la connexion
<.>Redémarrez MySQL, vérifiez sql_mode dans l'outil MySQL, cela montre que le résultat est le même que la configuration, mais le programme signale toujours la même erreur

Après une nouvelle recherche, j'ai J'ai soudainement réalisé le problème de la session globale, c'est-à-dire les deux instructions pour interroger sql_mode en tête de l'article, j'ai donc demandé quelle était la différence

paramètres des variables mysql Il existe deux manières,

un global une configuration, c'est-à-dire globale, qui agit sur le monde entier ;

une configuration de session, qui n'agit que sur la connexion en cours

Est-ce que ce sera possible ? sql_mode

dans la connexion actuelle Lorsque le programme laravel imprime sql_mode

[client]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
Copier après la connexion

, il s'avère que c'est le programme qui le définit

. La première chose qui me vient à l'esprit est mysql. Il y a un mode strict dans la configuration, je l'ai toujours activé et je l'ai défini sur false. Le problème a été résolu avec succès

$result = \DB::select(&#39;SELECT @@GLOBAL.sql_mode&#39;);
print_r($result);exit;
结果:
STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

$result = \DB::select(&#39;SELECT @@SESSION.sql_mode&#39;);
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
Copier après la connexion

Cela peut résoudre le problème. problème, mais basé sur la technologie, je veux juste comprendre comment il est écrit, et je ne veux pas le définir directement sur false,

Recherchez strict dans le fournisseur/laravel/framework /src/ILLumate/Database, et trouvez directement le code principal

    fichier : supplier/laravel/ framework/src/ILLumate/Database/Connectors/MySqlConnector.php
  • &#39;strict&#39; => false,
    Copier après la connexion
  • Le premier jugement directement détermine s'il existe une configuration de modes. Si c'est le cas, utilisez simplement ceci

pour le faire

protected function setModes(PDO $connection, array $config){
    if (isset($config[&#39;modes&#39;])) {
        $this->setCustomModes($connection, $config);
    } elseif (isset($config[&#39;strict&#39;])) {
        if ($config[&#39;strict&#39;]) {
            $connection->prepare($this->strictMode($connection))->execute();
        } else {
            $connection->prepare("set session sql_mode=&#39;NO_ENGINE_SUBSTITUTION&#39;")->execute();
        }
    }}
Copier après la connexion

Testez et résolvez le problème directement

Dans l'esprit de la recherche racine, continuons la lecture

Si strict = true

sera défini directement dans le programme sql_mode codé en dur, laravel distingue mysql 8.0.11 des autres versions

&#39;modes&#39; => [&#39;STRICT_TRANS_TABLES&#39;, &#39;NO_ZERO_IN_DATE&#39;, &#39;NO_ZERO_DATE&#39;, &#39;ERROR_FOR_pISION_BY_ZERO&#39;, &#39;NO_AUTO_CREATE_USER&#39;, &#39;NO_ENGINE_SUBSTITUTION&#39;],
Copier après la connexion

Puis si strict = false, définissez directement sql_mode sur NO_ENGINE_SUBSTITUTION

protected function strictMode(PDO $connection)
{
    if (version_compare($connection->getAttribute(PDO::ATTR_SERVER_VERSION), &#39;8.0.11&#39;) >= 0) {
        return "set session sql_mode=&#39;ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION&#39;";
    }

    return "set session sql_mode=&#39;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&#39;";
}
Copier après la connexion

Le problème est complètement résolu ici

La solution finale

$connection->prepare("set session sql_mode=&#39;NO_ENGINE_SUBSTITUTION&#39;")->execute();
Copier après la connexion

conservé strict = true et ajouté l'option modes Les paramètres à l'intérieur. sont la configuration sous-jacente de laravel, mais seulement supprimés ONLY_FULL_GROUP_BY

Résumé : Après avoir fait de nombreux détours et passé beaucoup de temps, le problème a finalement été résolu et il n'a pas été nécessaire de modifier quoi que ce soit. configuration de mysql

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:learnku.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal