Laravel 4 db raw query with IN in the WHERE clause doesn't work with parameter with MySql

别等时光非礼了梦想. 提交于 2019-12-13 18:12:51

问题


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.


回答1:


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);
}



回答2:


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.




回答3:


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!




回答4:


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
  )
);


来源:https://stackoverflow.com/questions/22387487/laravel-4-db-raw-query-with-in-in-the-where-clause-doesnt-work-with-parameter-w

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!