ホームページ  >  記事  >  PHPフレームワーク  >  mysqlのonly_full_group_by問題を解決するlaravelについて

mysqlのonly_full_group_by問題を解決するlaravelについて

藏色散人
藏色散人転載
2021-01-25 13:44:093003ブラウズ

次のコラムLaravelチュートリアルでは、laravelがmysを解決する方法を紹介します。 ql 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

方法はありませんこの問題を解決するには 回り道を避け、オンラインで見つかった方法に従って 1 つずつ試してください

解決策のアイデア

View sql_mode

select @@GLOBAL.sql_mode;SELECT @@SESSION.sql_mode

まず、mysql 設定ファイルを確認して変更します。my.cnf は非常に恥ずかしいです。my には ONLY_FULL_GROUP_BY がありません。クライアント設定に従って、[クライアント] 設定を追加します。

[mysqld]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

再起動mysql、MySQL ツールで sql_mode を確認すると、表示された結果は確かに設定と同じですが、プログラムは依然として同じエラーを報告します

もう一度検索した後、突然問題に気づきました。記事の先頭にある sql_mode をクエリする 2 つのステートメントであるグローバル セッションの違いについて質問しました。

mysql 変数の設定には 2 つの方法があります。 1 つはグローバル設定で、もう 1 つはグローバルです。 、全世界に作用します; 1 つはセッション構成セッションで、現在の接続にのみ作用します



それは起こりますか? 現在の接続に sql_mode を設定しているのは laravel ですconnection.

laravel プログラムが sql_mode
[client]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
を出力すると、それを設定したのはプログラムであることがわかります。

最初のこと頭に浮かぶのは mysql 設定に厳密モードがあります。私は常にそれをオンにして false に設定しています。問題はスムーズに解決されました。

$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

これで問題は解決できますが、ベースになっています。テクノロジーについては、それがどのように書かれているかを知りたいだけであり、直接 false に設定したくありません。

    vendor/laravel/framework/src/ILLuminate で strict を検索してください。 /Database フォルダーを開き、コア コードを直接見つけます。
  • ファイル:vendor/laravel/framework/src/ILLuminate/Database/Connectors/MySqlConnector.php
'strict' => false,

最初の判断は、存在するかどうかを直接決定します。モード設定。その場合は、これを使用してください

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();
        }
    }}

テストして、問題を直接解決してください

根本原因を探す精神で、次に読んでください。 on

Strict = trueの場合

ハードコーディングされたsql_mode、laravelはmysql 8.0.11を他のバージョンと区別します

'modes' => ['STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_pISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION'],

Then if strict = true false、sql_mode を NO_ENGINE_SUBSTITUTION に直接設定します

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'";
}

問題はここで完全に解決されます

最終解決策

$connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();

strict = true を維持し、mode オプションを追加します。内部のパラメータは次のとおりです。 laravel の基礎となる設定を削除しますが、ONLY_FULL_GROUP_BY

概要: 多くの回り道をし、多くの時間を費やした後、問題は最終的に解決され、何も変更する必要はありませんでした。 mysql

の設定

以上がmysqlのonly_full_group_by問題を解決するlaravelについての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。