1

When I do the following query as a DB:select DB:raw query against MySQL in Laravel 4 it returns no results. (Note, I've truncated the actual query for this example.)

SELECT user_id, email, first_name, last_name, photo_small
FROM users AS u
JOIN profiles AS p ON p.user_id = u.id
 WHERE email IN (?) ....

where $p= "email.address1@com","xyz.xxx@.edu" and $p is the parameter

Yet when I do the following

SELECT user_id, email, first_name, last_name, photo_small
FROM users AS u
JOIN profiles AS p ON p.user_id = u.id
 WHERE email IN ("email.address1@com","xyz.xxx@.edu") ....

I do get results.

I've confirmed the values of the parameters, checking the SQL and bindings with DB::getQueryLog() and verified results using a separate db tool.

I would really like to avoid the unparameterized query for obvious reasons, but can't seem to get it to return anything even though it is valid SQL

Any suggestions would be welcome.

Community
  • 1
  • 1
JohnL
  • 13,682
  • 4
  • 19
  • 23

4 Answers4

2

How about something like this to parameterize values on the fly? This is for a list of Ids, but I'm sure you can see how to adapt it to emails.

public function getDataByIds($idArray)
{
    $parametersString="";
    $parameters=[];
    for($i=0; $i<count($idArray);$i++)
    {
        $parameterName = ":id" . $i;
        $parametersString .= $parameterName . ",";
        $parameters[$parameterName]=$idArray[$i];
    }
    $parametersString=substr($parametersString, 0, -1);
    $query = $this->getQuery("SELECT blah WHERE id IN (".$parametersString.")");
    return DB::select(DB::raw($query), $parameters);
}
joelmdev
  • 11,083
  • 10
  • 65
  • 89
1

This approach doesn't work, because the underlying mechanism is PDO, and it requires a value per parameter. You are trying to trick it into accepting a comma seperated list of parameters but that will not work.

See PDO with "WHERE... IN" queries for an approach to this. You can take what majimboo provides and add some code that will go through your value array and generate your in statement as such:

WHERE id IN (:val1, :val2, etc)

Or you can possibly render it as:

WHERE id IN (?, ?, ?)

And then passing the array of actual replacement values should be accepted.

I agree with majimboo however, that you should be able to use the querybuilder for this query. It has the whereIn() method to help you with that portion of the query, and you would avoid having to write your own query syntax generation code.

Community
  • 1
  • 1
gview
  • 14,876
  • 3
  • 46
  • 51
1

I have a same boat with DB::select() ... I have not found any good solution yet, except this one:

PDO with "WHERE... IN" queries

$array = [...];
$stringList = implode(",", $array);
$result = DB::select('....... WHERE id IN ('.$stringList.')');

So the parameters are actually not parameters but prepared string and you can inject it into the SQL query. It's absolutely not elegant and not secure but I have found this one as the only one working solution. Make sure you have checked all possible cases when you create the substring before inject it!

Community
  • 1
  • 1
Sas Sam
  • 681
  • 4
  • 10
  • 25
0

Try something like:

$array = [...];                    // your array
$strArray = implode(",", $array);  // covert it to a comma delimited string
DB::raw("
...
WHERE email IN ($strArray)         // call the comma delimited string of the array
...
");

Should work the same with DB::select()
But why aren't you using Eloquent?


Also use single quote like: $p = "'email.address1@com', 'xyz.xxx@.edu'";


Just to make it clear

warning double checking

$results = DB::select('SELECT * FROM users WHERE id IN (?)', array($strArray));

another idea

DB::select( 
  DB::raw("SELECT * FROM my_table WHERE id IN (:strArray)"), array(
    'strArray' => $strArray
  )
);
majidarif
  • 18,694
  • 16
  • 88
  • 133