在Eloquent中的DUPLICATE KEY UPDATE

Sch*_*esi 3 laravel eloquent laravel-5.2

我刚开始laravel和所有我想要做的就是下面的查询工作雄辩:

INSERT INTO geschichte (geschichte_id, 
                        geschichte_text1, 
                        geschichte_text2, 
                        geschichte_text3) 
VALUES (:geschichte_id, 
        :geschichte_text1, 
        :geschichte_text2, 
        :geschichte_text3) 
ON DUPLICATE KEY 
UPDATE geschichte_id = :geschichte_id, 
       geschichte_text1 = :geschichte_text1, 
       geschichte_text2 = :geschichte_text2, 
       geschichte_text3 = :geschichte_text3;
Run Code Online (Sandbox Code Playgroud)

控制器功能

public function alterGeschichte(Request $request)
{
    $geschichte1 = new Geschichte;
    $geschichte2 = new Geschichte;
    $geschichte3 = new Geschichte;

    $geschichte1 = Geschichte::updateOrCreate(
       ['id' => 1],
       ['geschichte_text1' => $request->geschichte_text1]
    );
    $geschichte2 = Geschichte::updateOrCreate(
       ['id' => 2],
       ['geschichte_text2' => $request->geschichte_text2]
    );
    $geschichte3 = Geschichte::updateOrCreate(
       ['id' => 3],
       ['geschichte_text3' => $request->geschichte_text3]
    );

    $geschichte1->save();
    $geschichte2->save();
    $geschichte3->save();

    return redirect('/geschichte');
}
Run Code Online (Sandbox Code Playgroud)

更详细的问题

我不能让"重复密钥更新"部分工作.
每次更新时都会创建一个新条目.我希望每个条目的id始终相同,只是用该id覆盖旧条目.

我会非常感谢任何帮助.我几个小时都在努力...

更新

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGeschichteTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('geschichte', function (Blueprint $table) {
            $table->increments('id');
            $table->text('geschichte_text1');
            $table->text('geschichte_text2');
            $table->text('geschichte_text3');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('geschichte');
    }
}
Run Code Online (Sandbox Code Playgroud)

Ily*_*ich 10

从 Laravel 8 开始,就有了upsert模仿 SQLINSERT ON DUPLICATE KEY UPDATE功能的方法。

此查询生成器示例:

DB::table('flights')->upsert(
    [
        ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
    ], 
    ['departure', 'destination'], 
    ['price']
);
Run Code Online (Sandbox Code Playgroud)

等于以下 SQL 查询:

INSERT INTO flights (departure, destination, price) 
    VALUES ('Chicago', 'New York', 150)
    ON DUPLICATE KEY UPDATE price = 150;
Run Code Online (Sandbox Code Playgroud)

upsert方法有 3 个参数。

  1. 要插入或更新的值
  2. 唯一标识关联表中的记录的列
  3. 如果数据库中已存在匹配记录,则应更新的列数组

第二个参数中的列必须具有“主”或“唯一”索引。

完整文档


use*_*496 5

您希望在您希望独特的列上看起来没有唯一的密钥设置.为了使用on duplicate key update,您需要这样做,以便您的数据库服务器知道它是否需要插入或更新.

不幸的是,Laravel不支持on duplicate key update语法.这将是有用的,因为它试图插入并且如果它已经在表中,那么它将在一个查询中相应地更新列.

使用Laravel的updateOrCreate方法,它首先查询表以查看它是否需要生成插入或更新语句,然后相应地继续.你没有获得只运行一个查询的优势,但同时,它是Laravel,它处理所有额外的逻辑,所以这是一个轻微的权衡.

  • 有人建议在 Laravel 中使用 DUPLICATE KEY UPDATE 的原始解决方法:/sf/answers/3694784621/ (2认同)

Ale*_*ris 4

控制器中的大部分内容都不是必需的。我还有点担心您使用的数据库结构以及为什么要执行控制器中所示的任务。以下应该是您所需要的:

public function alterGeschichte(Request $request)
{
    Geschichte::updateOrCreate(
       ['id' => 1],
       ['id' => 1, 'geschichte_text1' => $request->geschichte_text1]
    );

    Geschichte::updateOrCreate(
       ['id' => 2],
       ['id' => 2, 'geschichte_text2' => $request->geschichte_text2]
    );

    Geschichte::updateOrCreate(
       ['id' => 3],
       ['id' => 3, 'geschichte_text3' => $request->geschichte_text3]
    );

    return redirect('/geschichte');
}
Run Code Online (Sandbox Code Playgroud)

如果这些正在创建新记录,很可能是因为没有具有这些 ID 的记录。

  • updateOrCreate 不会执行“ON DUPLICATE KEY UPDATE”,这可能会导致某些人出现问题。 (4认同)