在WHERE子句中使用IN的Laravel 4 db原始查询不能与MySql的参数一起使用

时间:2014-03-13 18:18:39

标签: mysql laravel-4

当我以DB作为以下查询时:在Laravel 4中选择DB:对MySql的原始查询,它不返回任何结果。 (注意,我已经截断了这个例子的实际查询。)

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 (?) ....

其中$ p =“email.address1@com”,“xyz.xxx @ .edu”和$ p是参数

然而,当我做以下

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") ....

我确实得到了结果。

我已经确认了参数的值,使用单独的数据库工具检查SQL和绑定与DB :: getQueryLog()和验证结果。

我真的希望避免使用未参数化的查询,原因很明显,但即使它是有效的SQL,也无法让它返回任何内容

欢迎任何建议。

4 个答案:

答案 0 :(得分:2)

这样的事情如何动态地参数化值?这是一个ID列表,但我相信你可以看到如何使它适应电子邮件。

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

答案 1 :(得分:1)

这种方法不起作用,因为底层机制是PDO,它需要每个参数的值。您试图欺骗它接受逗号分隔的参数列表,但这不起作用。

请参阅PDO with "WHERE... IN" queries了解相关方法。您可以使用majimboo提供的内容并添加一些将通过您的值数组的代码并生成您的in语句:

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

或者您可以将其渲染为:

WHERE id IN (?, ?, ?)

然后接受传递实际替换值的数组。

但我同意majimboo,您应该能够使用querybuilder进行此查询。它有whereIn()方法来帮助您查询该部分,并且您可以避免编写自己的查询语法生成代码。

答案 2 :(得分:1)

我和DB :: select()有一条船......我还没有找到任何好的解决方案,除了这个:

PDO with "WHERE... IN" queries

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

因此参数实际上不是参数,而是准备好的字符串,您可以将其注入SQL查询。它绝对不优雅而且不安全,但我发现这是唯一一个可行的解决方案。在注入之前,请确保在创建子字符串时检查了所有可能的情况!

答案 3 :(得分:0)

尝试类似:

$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
...
");

DB::select()的工作方式相同 但是你为什么不使用Eloquent?


也可以使用单引号:$p = "'email.address1@com', 'xyz.xxx@.edu'";


只是为了说清楚

警告双重检查

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

另一个想法

DB::select( 
  DB::raw("SELECT * FROM my_table WHERE id IN (:strArray)"), array(
    'strArray' => $strArray
  )
);