Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind parameters to a raw DB query in Laravel that's used on a model?

Re,

I have the following query:

$property =      Property::select(         DB::raw("title, lat, lng, (              3959 * acos(                  cos( radians(:lat) ) *                  cos( radians( lat ) ) *                  cos( radians( lng ) - radians(:lng) ) +                  sin( radians(:lat) ) *                  sin( radians( lat ) )              )          ) AS distance", ["lat" => $lat, "lng" => $lng, "lat" => $lat])     )     ->having("distance", "<", $radius)     ->orderBy("distance")     ->take(20)     ->get(); 

It doesn't work: Invalid parameter number: mixed named and positional parameters.

Does anyone know a trick or a workaround (I can obviously write the full query but prefer to use fluent builder).

like image 695
MarkL Avatar asked Jan 01 '14 01:01

MarkL


People also ask

What is DB :: Raw in laravel?

DB::raw() is used to make arbitrary SQL commands which aren't parsed any further by the query builder. They therefore can create a vector for attack via SQL injection.

What is fluent query builder in laravel?

The Fluent Query Builder is Laravel's powerful fluent interface for building SQL queries and working with your database. All queries use prepared statements and are protected against SQL injection. You can begin a fluent query using the table method on the DB class.

How does laravel query builder work?

In Laravel the database query builder provides an easy interface to create and run database queries. It can be used to perform all the database operations in your application, from basic DB Connection, CRUD, Aggregates, etc. and it works on all supported database systems like a champ.


2 Answers

OK, after some experimenting, here's the solution that I came up with:

$property =      Property::select(         DB::raw("title, lat, lng, (              3959 * acos(                  cos( radians(  ?  ) ) *                 cos( radians( lat ) ) *                  cos( radians( lng ) - radians(?) ) +                  sin( radians(  ?  ) ) *                 sin( radians( lat ) )              )        ) AS distance")     )     ->having("distance", "<", "?")     ->orderBy("distance")     ->take(20)     ->setBindings([$lat, $lng, $lat,  $radius])     ->get(); 

Basically, setBindings has to be called on the query. Wish this was documented!

like image 75
MarkL Avatar answered Sep 23 '22 00:09

MarkL


Old question, but if we have to repeat a variable, we have to change its key value in the bindings array.

    $property = Property::select(         DB::raw("title, lat, lng, ( 3959 * acos( cos( radians(:lat) ) *          cos( radians( lat ) ) * cos( radians( lng ) - radians(:lng) ) +          sin(radians(:lat_i) ) * sin( radians( lat ) ) ) ) AS distance"),         ["lat" => $lat, "lng" => $lng, "lat_i" => $lat]); 

That's enough.

like image 26
bluesky777 Avatar answered Sep 25 '22 00:09

bluesky777