logo

Extra Block Types (EBT) - Neue Erfahrung im Layout Builder❗

Extra Block Types (EBT) - gestylte, anpassbare Blocktypen: Diashows, Registerkarten, Karten, Akkordeons und viele andere. Eingebaute Einstellungen für Hintergrund, DOM Box, Javascript Plugins. Erleben Sie die Zukunft der Layouterstellung schon heute.

Demo EBT-Module EBT-Module herunterladen

❗Extra Absatztypen (EPT) - Erfahrung mit neuen Absätzen

Extra Paragraph Types (EPT) - analoger, auf Absätzen basierender Satz von Modulen.

Demo EPT-Module EPT-Module herunterladen

Scroll

Arbeiten mit der Datenbank in Drupal 7 – Lektion 11 – Merge-Abfragen (MERGE)

26/05/2025, by Ivan

Merge-Abfragen sind spezielle hybride Abfragen. Obwohl der Syntax-Standard dafür in SQL 2003 definiert wurde, unterstützt keine Datenbank diesen Syntax direkt. Allerdings bieten die meisten Datenbanken alternative Implementierungen mit spezifischem Syntax an. Der Merge-Query-Builder in Drupal abstrahiert das Konzept einer Merge-Abfrage in einem Objekt, das je nach Datenbank unterschiedlich kompiliert wird und deren Besonderheiten berücksichtigt.

Im Grunde kombiniert eine Merge-Abfrage eine Einfüge- (INSERT) und eine Aktualisierungsabfrage (UPDATE). Wenn eine Zeile mit dem definierten Schlüssel existiert, wird ein UPDATE ausgeführt, ansonsten ein INSERT. In vielen Fällen entspricht das folgendem Muster:

<?php
if (db_result(db_query("SELECT COUNT(*) FROM {example} WHERE id=:id", array(':id' => $id))->fetchField())) {
  // Update mit WHERE id = $id ausführen
}
else {
  // Insert, wobei id den Wert $id bekommt
}
?>

Die eigentliche Implementierung ist je nach Datenbank unterschiedlich. Beachten Sie, dass Merge-Queries zwar konzeptionell atomar sind, aber in der Praxis nur in manchen Datenbanken wie MySQL wirklich atomar ausgeführt werden.

Beispiel „Einfach machen“

<?php
db_merge('example')
  ->key(array('name' => $name))
  ->fields(array(
      'field1' => $value1,
      'field2' => $value2,
  ))
  ->execute();
?>

Im Beispiel operieren wir auf der Tabelle „example“. Wir definieren einen Schlüssel 'name' mit dem Wert $name sowie ein Feld-Array mit Werten. Existiert bereits eine Zeile mit diesem 'name', werden die Felder 'field1' und 'field2' aktualisiert. Falls nicht, wird eine neue Zeile mit diesen Werten angelegt.

Unterschiedliche Werte je nach Existenz

Manchmal möchte man unterschiedliche Werte setzen, je nachdem, ob die Zeile existiert. Dafür gibt es zwei Möglichkeiten:

<?php
db_merge('example')
  ->key(array('name' => $name))
  ->fields(array(
      'field1' => $value1,
      'field2' => $value2,
  ))
  ->updateFields(array(
    'field1' => $alternate1,
  ))
  ->execute();
?>

Im Vergleich zum ersten Beispiel wird bei einer existierenden Zeile nur 'field1' mit $alternate1 aktualisiert. Existiert die Zeile nicht, werden die Felder gemäß fields() gesetzt. Die Methode updateFields() akzeptiert entweder ein assoziatives Array oder zwei numerische Arrays für Felder und Werte, die in der gleichen Reihenfolge stehen müssen.

<?php
db_merge('example')
  ->key(array('name' => $name))
  ->fields(array(
      'field1' => $value1,
      'field2' => $value2,
  ))
  ->expression('field1', 'field1 + :inc', array(':inc' => 1))
  ->execute();
?>

In diesem Beispiel wird bei einer existierenden Zeile das Feld 'field1' um 1 erhöht. Das ist nützlich für Zähler-Updates bei Ereignissen. Existiert die Zeile nicht, werden die Felder 'field1' und 'field2' mit den angegebenen Werten gesetzt. Die Methode expression() kann für jedes Feld aufgerufen werden, um einen SQL-Ausdruck zu definieren. Parameter sind Feldname, SQL-Ausdruck und optional ein Array mit Platzhalterwerten.

Es ist nicht notwendig, dass das Feld in expression() auch in fields() definiert ist.

Einschränkung bei Updates

<?php
db_merge('example')
  ->key(array('name' => $name))
  ->fields(array(
      'field1' => $value1,
      'field2' => $value2,
  ))
  ->updateExcept('field1')
  ->execute();
?>

Die Methode updateExcept() akzeptiert entweder ein Array oder mehrere Felder als Parameter. Felder, die in updateExcept() angegeben sind, werden bei existierenden Zeilen nicht aktualisiert. Im Beispiel wird bei existierender Zeile nur 'field2' mit $value2 gesetzt, 'field1' bleibt unverändert. Existiert die Zeile nicht, wird auch 'field1' auf $value1 gesetzt.

Priorität der Methoden

Das API erlaubt es, Anfragen so zu definieren, dass sie keinen Sinn ergeben. Um Fehler zu minimieren, gelten folgende Regeln:

  • Felder, die mit expression() gesetzt werden, haben Vorrang vor updateFields() und updateExcept().
  • Felder, die in updateFields() definiert sind, werden von updateExcept() ignoriert.
  • Nur Felder, die in updateFields() angegeben sind, werden bei existierenden Zeilen aktualisiert. Andere Felder bleiben unverändert.

Es ist möglich, sinnlose Anfragen zu definieren, dies sollte vermieden werden.