Heim  >  Artikel  >  Datenbank  >  Fügen Sie eine Zeile in eine Datenbank ein, die keine Primärschlüssel oder eindeutigen Einschränkungen verwendet

Fügen Sie eine Zeile in eine Datenbank ein, die keine Primärschlüssel oder eindeutigen Einschränkungen verwendet

Linda Hamilton
Linda HamiltonOriginal
2024-10-19 10:52:29258Durchsuche

Upsert a row in a DB that doesn

Während meiner 7-jährigen Karriere als Programmierer habe ich die meiste Zeit über ein ORM mit SQL interagiert. Eine Funktion von Laravel's Eloquent ORM, die ich besonders nützlich finde, ist die updateOrInsert()-Methode:

DB::table('posts')
    ->updateOrInsert(
        ['slug' => 'about'], // matching condition
        ['content' => 'Like and subscribe'] // created or updated values
    );

Im obigen Beispiel sucht Eloquent nach einer Zeile in der Beitragstabelle, in der der Slug „about“ entspricht. Wenn eine Zeile mit diesem Slug vorhanden ist, aktualisiert Eloquent den Inhalt dieser Zeile auf „Gefällt mir und abonnieren“. Wenn eine Zeile mit diesem Slug nicht existiert, erstellt Eloquent eine neue Zeile mit dem Slug „about“ und dem Inhalt „Gefällt mir und abonnieren“.

Das Problem: kein Primärschlüssel oder eindeutige Einschränkungen

Ich schreibe derzeit ein Migrationsskript, um Seitendaten von einer alten WordPress-Site auf eine neue WordPress-Site zu verschieben. Das Skript stellt eine Verbindung zur Datenbank der alten Site her und erstellt dann eine SQL-Datei, die in die Datenbank der neuen Site importiert werden kann. Auf der neuen Website wurden bereits einige Seiten manuell verschoben, deren Inhalt ist jedoch möglicherweise veraltet. Wenn auf der neuen Website bereits eine Seite vorhanden ist, möchten wir sie nicht erneut erstellen: Wir möchten die bereits vorhandene Seite aktualisieren. Wir können feststellen, ob die Seite bereits existiert, indem wir die Spalte „post_name“ in der WordPress-Datenbank verwenden, die dem URL-Slug der Seite entspricht.

Wenn der Postname der Primärschlüssel wäre, könnten wir mit einer REPLACE-Anweisung etwas Ähnliches wie die Methode createOrUpdate() von Eloquent erreichen, aber der Postname ist nicht der Primärschlüssel.

Wenn der Postname eine Eindeutigkeitsbeschränkung hätte, könnten wir etwas Ähnliches wie die Methode createOrUpdate() von Eloquent mit einer INSERT ... ON DUPLICATE KEY UPDATE-Anweisung erreichen, aber der Postname hat keine Eindeutigkeitsbeschränkung.

Ah, die Freuden von WordPress.

Ich habe mir die IF-Anweisung von MySQL angesehen, aber die IF-Anweisung funktioniert nur in gespeicherten Prozeduren, Triggern und Funktionen. Ich wollte keine gespeicherten Prozeduren in der SQL-Datei erstellen, die ich in die Datenbank der neuen Site importieren würde, also musste ich nach anderen Optionen suchen.

Die Lösung: 2 Aussagen

Die einfachste Lösung, die ich finden konnte, um die Funktionalität von updateOrInsert() von Eloquent in reinem SQL zu emulieren, bestand darin, das Problem in zwei Teile zu zerlegen:

  1. Aktualisieren Sie alle vorhandenen Zeilen mit einem passenden Slug.
  2. Erstellen Sie eine neue Zeile, wenn keine Zeilen mit passenden Slugs vorhanden sind.

So sieht das in der Praxis aus:

-- Update the post if it already exists.

UPDATE wp_posts
SET post_type = 'page',
    post_title = 'About',
    post_content = 'Like and subscribe'
WHERE post_name = 'about';

-- Create a new post if it does not exist.

INSERT INTO wp_posts (post_name, post_type, post_title, post_content)
SELECT 'about', 'page', 'About', 'Like and subscribe'
WHERE NOT EXISTS (
    SELECT 1
    FROM wp_posts
    WHERE post_name = 'about'
);

HINWEIS:In diesem Beispiel werden aus Gründen der Kürze und Klarheit viele der erforderlichen wp_posts-Spalten von WordPress weggelassen.

Das Erlernen der INSERT ... SELECT-Anweisung war für mich der „Aha“-Moment. Es ist beabsichtigt, die Ergebnisse einer Abfrage aus einer anderen Tabelle zu verwenden, um viele Einfügungen gleichzeitig durchzuführen. Sie können jedoch die Funktionen von SQL nutzen und missbrauchen, indem Sie Ihre eigenen Werte bereitstellen und die Einfügung nur durchführen, wenn ein Beitrag mit dem Postnamen „about“ nicht existiert.

Ist dies die eleganteste und effizienteste Lösung für dieses Problem? Wahrscheinlich nicht. Aber es ist gut genug für eine einmalige Migration einer WordPress-Site und ermöglicht es Ihnen, eine Zeile zu aktualisieren oder einzufügen, ohne dass gespeicherte Prozeduren oder Anwendungslogik erforderlich sind. Hoffentlich hilft Ihnen dieser Beitrag beim Schreiben leistungsfähiger Abfragen ohne die Hilfe eines ORM.

Das obige ist der detaillierte Inhalt vonFügen Sie eine Zeile in eine Datenbank ein, die keine Primärschlüssel oder eindeutigen Einschränkungen verwendet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn