4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LaravelクエリビルダーでIDのあいまい検索をする

Posted at

概要

LaravelのクエリビルダーでIDのあいまい検索(1を含むIDを検索するなど)を実装する際に詰まったので,問題のあったコードとその解決策を残しておきます.

環境

Laravel 5.5
Postgresql 9.6

問題点

SQLインジェクションを避けるために,クエリビルダーのwhereRawメソッドでバインディングを行おうとしましたが,エラーが発生して実行できませんでした.

問題のあるコード

以下はすべて動作しません.

$query->whereRaw("CAST(books.id AS TEXT) LIKE %?%",[1]);        //1
$query->whereRaw("CAST(books.id AS TEXT) LIKE % ? %",[1]);      //2
$query->whereRaw("CAST(books.id AS TEXT) LIKE '%?%'",[1]);      //3
$query->whereRaw("CAST(books.id AS TEXT) LIKE '% ? %'",[1]);    //4
$query->whereRaw("CAST(books.id AS TEXT) LIKE '%' ? '%'",[1]);  //5

1,2の場合は,

WHERE CAST(books.id AS TEXT) LIKE %1%

というSQLが実行されます.バインディングはされますが,%1%の部分を' 'で囲めていないためにエラーが生じます.

3,4では,?を' 'で囲んでしまうと,

WHERE CAST(books.id AS TEXT) LIKE '%?%'

というSQLが発行されますが,?が文字列として扱われるためバインディングができず,エラーが生じます.

5の場合は

WHERE CAST(books.id AS TEXT) LIKE '%' 1 '%'

というSQLが発行されますが,'%' 1 '%'の部分がエラーとなってしまいます.

解決策

次のようにすると動作しました.

$query->whereRaw("CAST(books.id AS TEXT) LIKE '%' || ? || '%'",[1]);

この場合だと,

WHERE CAST(books.id AS TEXT) LIKE '%' || 1 || '%'

というSQLが発行され,'%' || 1 || '%'の部分は結合されて'%1%'となり,目的のSQLが発行っされます.

参考

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?