🐘

【Larevel9 + MySQL】LIKEが含まれるSQLをDB::select()に渡すとSQLのエラーが出る場合の解決方法

2022/10/31に公開

概要

LIKEが含まれるSQLをクエリビルダで

$sql = "
    /* SQL文(中略) */
    WHERE column LIKE '%?%'
    /* SQL文(中略) */
";
$placeholder = [
    "検索したい語句"
];
$result = DB::select($sql, $placeholder);

みたいな感じで実行したら、SQLSTATE[HY093]: Invalid parameter number at ...というエラーが出た。

エラーの文章からパラメータの数が合っていないと思ったので確認すると

  • ?の数と$placeholderに渡した値の数は同じで問題ない
  • laravel.logにパラメータ付きで出力したSQLをデータベース管理ソフトで実行するとエラーにならない(出力方法は https://hapicode.com/php/laravel-tosql.html を参考にさせていただきました。)

という結果。エラーに書いてあることと状況が一致しなかった。

解決方法

LIKEで比較するパラメータの前後に”%”を使用する場合は’%?%’ではなく、CONCAT()関数を使い

$sql = "
    /* SQL文(中略) */
    WHERE column LIKE CONCAT(‘%’, ?, ‘%’)
    /* SQL文(中略) */
";
$placeholder = [
    "検索したい語句"
];
$result = DB::select($sql, $placeholder);

とすると問題なく動作した。
"+"で文字列結合して

$sql = "
    /* SQL文(中略) */
    WHERE column LIKE ‘%’ + ? + ‘%’
    /* SQL文(中略) */
";

でも可能みたい。DBの種類によってどちらかが非対応だった場合は使い分ける必要があるかも。

Discussion