質問: Laravel5.4.30で、SQL文をベタで書きたいがエラーが発生して困っています。 ``` var_dump(DB::select('select * from user where name like "%?%"',['佐藤'])); exit(); ``` ↓ `SQLSTATE[HY000]: General error: 25 bind or column index out of range` これは何故でしょうか? なお、これはコントローラーに書いております。 コードはこちらを参考に書いております。 ↓引用もとコード > > $results=DB::select('select * from users where id=?',['1']); > > > LaravelではDBアクセスをするときに、ORM?と言うものを使わなければいけないのでしょうか? 10年以上SQLをベタで書いてきている私は、今まで書いたSQLをLaravelに移行させるのにORMを使うのが面倒で...... ご存知の方がいらっしゃいましたら、ご教示ください。 お願い致します。 --- また、プレースホルダーを、「?」ではなく、「:id」のように記述することは可能でしょうか。 こちらもご存知でしたら、ご教示ください。 よろしくお願いいたします。
回答: 修正依頼に書いてしまったのですが、ちょっと幾つか補足を兼ねて。 `DB::select('select * from user where name like "%?%"',['佐藤'])`ではなく`DB::select('select * from user where name like ?',['%佐藤%'])`ではどうでしょうか? Laravelは内部的にPDOを利用しており、bindValueを利用してバインディングを行っているので、SQL内でダブルクォーテーションでくくる必要はないと思います。 ORMを利用するかに関しては、使わなくて大丈夫です。(ORMを基本とする機能は使えなくなってしまいますが。。。) 特に既存サービスの移行等の場合はORMに適応させる作業自体に時間がかかってしまうため、あまりやらないと思います。 また、名前付きプレースホルダを利用したいとのことですが、恐らく思われている通りの書き方で動作します。 ``` DB::select('select * from user where name like :name',['name' => '%佐藤%']) ``` こんな感じですね。 Laravel内部ではこんな感じにbindingをやってます。 ``` foreach ($bindings as $key => $value) { $statement->bindValue( is_string($key) ? $key : $key + 1, $value, is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR ); } ```