Laravel:GroupByでSQLSTATE[42000]:Syntax error or access violation: 1055発生
Laravel:GroupByしたらエラーが発生
操作性を上げようとGroupByで重複削除しようと画策し組んでみたところエラーが発生。
1 2 3 |
$productcodes = Productconverter::where('itemcode_id',$item->id) ->groupBy('product_id') ->get(); |
実行 ⇒ SQLSTATE[42000]:Syntax error or access violation: 1055
調べてみたらEloquantではGroup Byは使えないとの事。
それならと思いクエリビルダで組んでみましたがこれもダメ。
う~ん、どうしたら…と言うことで調べた事をまとめます。
Laravelでgroupbyを使う方法は2つある
- config\database の値をイジる
- 直接SQLを書く
Laravelでは基本的に使えない様にしているようです。
そんな…。
マニュアルを見ると「使いたかったらインジェクション攻撃に注意して直接SQL発行してね」と書いてあります。
なるほど。
config\database の値をイジる
Laravelフォルダの config\database にGroupByを規制している場所があるそうです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8', 'collation' => 'utf8_general_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], |
この中の【’strict’ => true】が原因の様で、値を【 false 】に変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8', 'collation' => 'utf8_general_ci', 'prefix' => '', 'strict' => false, 'engine' => null, ], |
この strict はGroupBy以外にもいろいろ規制しているとの事。
う~ん、よく解らないからこそこういう所いじるのは怖いのです。
と言うことで、GroupByだけ解除する方法は無いか探してみました。
結果、modes を追加して許可するものを決めれるらしい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8', 'collation' => 'utf8_general_ci', 'prefix' => '', 'strict' => true, 'modes' => [ // 'ONLY_FULL_GROUP_BY', 'STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_ENGINE_SUBSTITUTION', ], 'engine' => null, ], |
えっ、それもレベル高いです…。
他のエラーが生じた時、ココが原因となっても嫌なので、素直にマニュアルに従う事にしました。
直接SQLを書く
直接書く事で「インジェクション攻撃が…」とはなりますが、まぁそんなに直接書くパートがある訳じゃないので。
1 2 3 4 |
$productcodes = Productconverter::where('itemcode_id',$item->id) ->selectRaw('product_id') ->groupBy('product_id') ->get(); |
うん、狙い通りに動いてます。
まとめ
DBを扱う以上、グループにまとめて集計するなんて事よくあります。
そんな時は頻度に応じて【直接書く】【コンフィグいじる】を選べばよさそうですね。
私の作成中のアプリでは頻度が少ないので【直接書く】で行こうと思います。
-
前の記事
Amazonの独占禁止法違反の疑いについて 2019.02.27
-
次の記事
Laravel:文字列カラムを結合した値でViewのSelectを作る 2019.03.01