为什么 Laravel updateOrCreate() 和 upsert() 都需要参数来唯一标识记录?



updateOrCreate()&upsert()做同样的事情,插入或更新,我认为它们都生成SQLINSERT INTO ON DUPLICATE KEY。因此,我觉得提供唯一标识记录的论据似乎没有必要。

为什么他们需要";第二个参数列出了唯一标识关联表中记录的列">

我能想到的原因可能是,在某些情况下,他们不会生成sqlINSERT INTO ON DUPLICATE KEY,因此他们可能需要参数来唯一标识记录?但事实是这样的吗?

updateOrCreate方法找到一个与作为第一个参数传递的约束匹配的记录,如果找到该记录,它将更新与作为第二个参数传递属性的匹配

如果没有找到匹配的记录,将创建同时将约束作为第一个参数传递和将属性作为第二个参数传递的记录

我检查了Laravel来源,它证实了我的怀疑,对于upsert(),请参阅https://github.com/illuminate/database/blob/master/Query/Grammars/MySqlGrammar.php#L164

它生成sqlinsert on duplicate key update,但根本没有使用$uniqueBy参数(不应该(

public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
{
$sql = $this->compileInsert($query, $values).' on duplicate key update ';
$columns = collect($update)->map(function ($value, $key) {
return is_numeric($key)
? $this->wrap($value).' = values('.$this->wrap($value).')'
: $this->wrap($key).' = '.$this->parameter($value);
})->implode(', ');
return $sql.$columns;
}

对于updateOrCreate(),它实际上是NOT生成insert on duplicate key update,但生成两个sql子句!!

https://github.com/illuminate/database/blob/master/Eloquent/Builder.php#L469

public function updateOrCreate(array $attributes, array $values = [])
{
return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
$instance->fill($values)->save();
});
}

在这里不容易看到生成的sql子句,但检查日志,它是两个子句,一个是insert into,一个update

最新更新