在Laravel 5.4中,如何在DB::raw中使用数组绑定的WHERE语句?

10

我正在尝试在Laravel DB中的原始WHERE IN查询中绑定一个数组。

例如:

$arr = [1,2,3];
DB::select(DB::raw("select * from test1 WHERE id IN ? "), [$arr]);

由于某种原因,数组未被更改为以下查询:

select * from test1 WHERE id IN (1,2,3)

有人知道我能以某种方式做到这一点吗?


尝试:DB::select(DB::raw("select * from test1 WHERE id IN ? "), $arr); - er.irfankhan11
6个回答

7
$arr = [1,2,3];
$placeholders = implode(",", array_fill(0, count($arr), '?'));

DB::select("select * from test1 WHERE id IN ($placeholders)", $arr);

这个例子:

  1. 支持任意长度的数组
  2. 不包含循环
  3. 安全地传递参数

在这个例子中,我创建了一个新的数组,并使用与原始数组长度相同数量的问号来填充它。然后我将新数组用逗号分隔拼接成字符串 "?,?,?, ..."。接下来,我将这个子字符串插入到圆括号操作符 "IN" 中间。最后,将原始数组作为 select 函数的第二个参数传递。结果是,在 "IN" 操作符中,每个数组元素都有自己的占位符。


1
虽然这可能回答了问题,但最好还包括一个解释为什么它解决了问题(它是如何工作的),这样任何未来的读者都可以从中学习。 - El_Vanja
我同意上面的评论。这个答案中的代码很好,但是没有解释为什么这样做有效,为什么需要这样做,以及这个答案比其他现有的答案更好的原因。 - apokryfos
@El_Vanja 这个示例支持任何长度的数组。不包含循环。安全地传递参数。 而且这个示例之所以有效,是因为我用一定数量的问号填充了一个新数组,该数量等于参数数组的元素数量。然后我将数组粘合在一起,用逗号分隔,得到“?,?,?,...”。然后我在括号运算符“IN”之间插入这个子字符串。并将项目数组本身作为选择函数的第二个参数传递。结果,元素数组中的每个元素都有自己的占位符在“IN”运算符中。 - nilecrocodile
@nilecrocodile 是的,由于我的经验,我可以解释发生了什么。我不是为自己要求解释,我想指出你应该始终在答案本身中包含解释。这样,当有人没有经验阅读它时,他们至少可以对这里发生的事情有一些大致的了解。我建议您编辑答案并将您的评论内容包含在其中。有些人只是浏览评论,可能会错过提供的其他信息。 - El_Vanja

5

在 Laravel 中尝试:

$arr = [1,2,3];
$result = DB::table('test1')->whereIn('id', $arr)->get();
dd($result);

并且使用这个作为你的原始查询:

$arr = [1,2,3];
$arr = join(",",$arr);
$result =  DB::select(DB::raw("SELECT * FROM test1 WHERE id IN (".$arr.")"));
dd($result);

为了防止SQL注入,您可以使用以下类似的方法:
 $arr = [1,2];
 $arr = join(",",$arr);
 $result =  DB::select(DB::raw("SELECT * FROM test1 WHERE id IN (?,?)"),$arr);
 dd($result);

它将适用于您。


通常这样做是可以的,但由于我在原始查询中使用了其他内容,所以我必须在原始查询中执行此操作。 - MrChrissss
我已经编辑了我的帖子,包括原始查询,请检查一下。 - gaurav
1
@gauraw 你不需要计算 $arr 来准备一个“?”块。 - Davuz
@Davuz 这只是一个例子,我们可以计算 $arr 来准备一个相应的块。 - gaurav

1

通常这样做是可以的,但我必须在原始查询中执行此操作,因为我在原始查询中使用了其他内容。 - MrChrissss

0

我稍微优化了@nilecrocodile的代码,这样我们就不需要构建数组并从中创建字符串。相反,我们将以这种方式创建占位符字符串:

$placeholders = substr(str_repeat(', ?', count($arr)), 2);

DB::select("select * from test1 WHERE id IN ($placeholders)", $arr);

0

或者 Eloquent:

$q= TestModel::where('id',$arr)->get();

在复杂查询中使用原生查询没问题,但在简单查询中为什么不使用 Eloquent 呢 ;) - Nasr
是的,我知道我在一般性地说话,没问题兄弟,祝你好运^^ - Nasr

0

尝试:

$array = [2,5,9,7,5];
$arrPos = [];
$arrBind = [];
foreach ($array as $pos => $id) {
    $arrPos[] = ":id_{$pos}";
    $arrBind["id_{$pos}"] = $id;
}

$sql = 
"  SELECT * FROM test1 WHERE id IN (".implode(', ', $arrPos).") ";
$rs = DB::select($sql, $arrBind);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接