代码之家  ›  专栏  ›  技术社区  ›  Qiulang

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

  •  0
  • Qiulang  · 技术社区  · 3 年前

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

    他们为什么需要 "the second argument lists the column(s) that uniquely identify records within the associated table." ?

    我能想到的原因可能是在某些情况下他们不生成sql 在重复的密钥上插入 所以他们可能需要参数来唯一地识别记录?但事实是这样的吗?

    1 回复  |  直到 3 年前
        1
  •  2
  •   Mahmoud Magdy    3 年前

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

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

        2
  •  0
  •   Qiulang    3 年前

    我查了一下Laravel的消息来源,它证实了我的怀疑,因为 upsert() 提到 https://github.com/illuminate/database/blob/master/Query/Grammars/MySqlGrammar.php#L164

    它生成sql insert 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() 事实上确实如此 不是 生成 重复密钥更新时插入 但是 2 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