ここで紹介する内容は、弊社で確認した一例です。
本ページを参考に作業をされ、何らかのトラブルや損失・損害等が発生しましても一切責任を負えません。自己責任でお願いします。
MySQL 5.7でエラーが発生するようになった
今までは、MySQLのバージョン5.5を利用していたのだが、レンタルサーバー業者の都合で、バージョン5.7のみが利用できる状況になってしまった。
すると、バージョン5.5では発生していなかったのに、バージョン5.7では、
Error: SQLSTATE[HY000]: General error: 3065 Expression #1 of ORDER BY clause is not in SELECT list, references column 'xxxxxxxxx.Category.order' which is not in SELECT list; this is incompatible with DISTINCT
のエラーが発生してしまった。
DISTINCT しているにもかかわらず SELECT 句に存在していないカラムでソートをしてはいけないというエラーなのだが、バージョン5.5では正常に動作していた。この状態で問題が発生しないことが分かっているので、エラーが出ないようにする方法を探ってみた。
バージョン5.5 との違い
次の SQL コマンドを実行してみると、
mysql> SELECT @@GLOBAL.sql_mode;
バージョン5.5では、空であるのに対して、バージョン5.7では、
ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
といった値が返ってきた。
このうち、
ONLY_FULL_GROUP_BY
がエラーを発生させている設定らしい。
ならば接続時に、
SET sql_mode = 'NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
といった SQL コマンドを実行できれば良いのではないだろうか。
CakePHP 2 で接続時に実行するSQLをカスタマイズする
CakePHP ではデータベースの接続に関する設定を、app/Config/database.php で行うようになっています。
デフォルトでは、
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'user',
'password' => 'password',
'database' => 'database_name',
'prefix' => '',
//'encoding' => 'utf8',
);
のようになっています。
ここに、「settings」キーを追加します。
今回は、
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'user',
'password' => 'password',
'database' => 'database_name',
'prefix' => '',
//'encoding' => 'utf8',
'settings' => array(
"'NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'",
),
);
としました。
これで、上記のエラーは発生しなくなりました。