4 Stimmen

Wie implementiert man INSERT ON DUPLICATE KEY UPDATE aka upsert in CakePHP 3?

Ich nutze CakePHP 3 und MySQL.

Ich möchte eine INSERT ON DUPLICATE KEY UPDATE auch bekannt als upsert Abfrage über das CakePHP 3 Modell implementieren.

Gegeben sei die folgende Tabelle:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  17 |
|  3 | Sally    |  23 |
+----+----------+-----+

wo id der Primärschlüssel und username ein eindeutiger Index ist

Wenn ich die folgenden Werte habe, die auf upsert warten:

Felicia, 27
Timmy, 71

Erwarte ich das folgende Ergebnis nach dem upsert:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  71 |
|  3 | Sally    |  23 |
|  4 | Felicia  |  27 |
+----+----------+-----+

I know how to do upsert in MySQL query:

INSERT INTO `users` (`username`, `age`) 
VALUES ('Felicia', 27), ('Timmy', 71) 
ON DUPLICATE KEY UPDATE 
`username`=VALUES(`username`),`age`=VALUES(`age`);

I know how to do this in more than a single query in CakePHP3.

   $newUsers = [
        [
            'username' => 'Felicia',
            'age' => 27,
        ],
        [
            'username' => 'Timmy',
            'age' => 71,
        ],
    ];

    foreach ($newUsers as $newUser) {
        $existingRecord = $this->Users->find()
            ->select(['id'])
            ->where(['username' => $newUser['username']])
            ->first();

        if (empty($existingRecord)) {
            $insertQuery = $this->Users->query();
            $insertQuery->insert(array_keys($newUser))
                ->values($newUser)
                ->execute();
        } else {
            $updateQuery = $this->Users->query();
            $updateQuery->update()
                ->set($newUser)
                ->where(['id' => $existingRecord->id])
                ->execute();
        }
    }

Was ich wissen möchte ist:

Gibt es eine Möglichkeit, upsert mit CakePHP 3 in einer Zeile zu machen, auch wenn ich Verkettung (chaining) verwende?

Bitte geben Sie an, wie ich das umsetzen kann.

6voto

Kim Stacks Punkte 9775

Unter Verwendung der Antwort auf https://stackoverflow.com/a/24990944/80353 möchte ich das mit dem im Fragebeispiel gegebenen Code neu formulieren.

Um upsert auf die folgenden Datensätze auszuführen

Felicia, 27
Timmy, 71

in diese Tabelle

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  17 |
|  3 | Sally    |  23 |
+----+----------+-----+

ist es am besten, es wie folgt zu schreiben

$newUsers = [
    [
        'username' => 'Felicia',
        'age' => 27,
    ],
    [
        'username' => 'Timmy',
        'age' => 71,
    ],
];

$columns = array_keys($newUsers[0]);

$upsertQuery = $this->Users->query();

$upsertQuery->insert($columns);

// Nach dem Insert muss clause('values') AUSGEFÜHRT werden
$upsertQuery->clause('values')->values($newUsers);

$upsertQuery->epilog('ON DUPLICATE KEY UPDATE `username`=VALUES(`username`), `age`=VALUES(`age`)')
                ->execute();

Siehe hier für Details zum epilog

Siehe hier für Details dazu, wie man mehrere Datensätze in einer einzigen Abfrage einfügt

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X