gpt4 book ai didi

mysql - Laravel 参数绑定(bind)导致偶尔出现 MySQL 一般错误

转载 作者:行者123 更新时间:2023-11-29 15:41:57 26 4
gpt4 key购买 nike

我有一个整数数组,需要作为一批行插入。每行都需要一些其他数据。

$ids = [1,2]
$thing = 1
$now = Carbon::now(); // This is just a timestamp.
$binding_values = trim(str_repeat("({$thing}, ?, '{$now}'),", count($ids)), ',');

字符串$binding_values看起来像这样:

“(1, ?, '2019-01-01 00:00:00'), (1, ?, '2019-01-01 00:00:00')”

然后我准备查询字符串并将参数绑定(bind)到它。使用 IGNORE 是因为我在表上有一个复合唯一索引。不过,它似乎与问题无关,因此我省略了详细信息。

DB::insert("
INSERT IGNORE INTO table (thing, id, created_at)
VALUES {$binding_values}
", $ids);

几乎一直有效,但时不时地我会收到错误SQLSTATE[HY000]:一般错误:2031

我执行此参数的方式是否与 Laravel 绑定(bind)了某种反模式?此错误的根源可能是什么?

因为该方法不存在注入(inject)风险,并且该方法不可能扩展到有注入(inject)风险的用例,所以我对其进行了修改以烘焙所有参数并跳过参数绑定(bind)。到目前为止我还没有看到任何错误。

我仍然想知道是什么可能导致此行为,以便我将来可以更好地管理它。如果您有任何见解,我将不胜感激。

最佳答案

除了将参数烘焙到查询中之外,我没有发现您的查询有什么大问题,这很容易受到 SQL 注入(inject)的影响。

据我所知,您的问题是您需要 INSERT ÌGNORE INTO,Laravel 不支持开箱即用。您是否考虑过使用像staudenmeir/laravel-upsert这样的第三方包?

另一种方法是将查询包装在事务中并首先选择现有条目,这样您就有机会不再插入它们:

$ids   = [1, 2];
$thing = 1;
$time = now();

DB::transaction(function () use ($ids, $thing, $time) {
$existing = DB::table('some_table')->whereIn('id', $ids)->pluck('id')->toArray();
$toInsert = array_diff($ids, $existing);

$dataToInsert = array_map(function ($id) use ($thing, $time) {
return [
'id' => $id,
'thing' => $thing,
'created_at' => $time
];
}, $toInsert);

DB::table('some_table')->insert($dataToInsert);
});

这样,您将只插入尚不存在的内容,但您也将保留在查询生成器的框架功能内。唯一的缺点是,由于第二次往返数据库,速度会稍微慢一些。

关于mysql - Laravel 参数绑定(bind)导致偶尔出现 MySQL 一般错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57542386/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com