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
18/06/2025, by Ivan

Merge-Anfragen stellen eine besondere Art von Hybridanfrage dar. Obwohl die Syntax dafür in der SQL-2003-Spezifikation definiert ist, unterstützt praktisch keine Datenbank die Standardsyntax. Allerdings bieten die meisten eine alternative Implementierung mit syntaxspezifischen Varianten für die jeweilige Datenbank an. Der Merge-Query-Builder in Drupal abstrahiert das Konzept der Merge-Anfrage in ein strukturiertes Objekt, das mit der entsprechenden Syntax für jede Datenbank kompiliert werden kann. Sie werden manchmal auch als "UPSERT"-Anfragen bezeichnet, eine Kombination aus UPDATE und INSERT.

Im allgemeinen Sinne ist eine Merge-Anfrage eine Kombination aus Einfüge- (Insert) und Aktualisierungsanfrage (Update). Wenn eine bestimmte Bedingung erfüllt ist, z.B. wenn eine Zeile mit einem bestimmten Primärschlüssel bereits existiert, wird ein Update ausgeführt. Wenn nicht, erfolgt ein Insert. Im häufigsten Fall entspricht das Folgendem:

if ($connection->query("SELECT COUNT(*) FROM {example} WHERE id = :id", [':id' => $id])->fetchField()) {
  // Führe ein Update mit WHERE id = $id aus
}
else {
  // Führe ein Insert aus und füge $id als id ein
}

Die tatsächliche Implementierung variiert stark von Datenbank zu Datenbank. Beachten Sie, dass Merge-Anfragen konzeptionell eine atomare Operation darstellen, sie aber je nach konkreter Datenbankimplementierung tatsächlich atomar sein können oder auch nicht. Zum Beispiel ist die MySQL-Implementierung eine einzelne atomare Anfrage, der oben dargestellte Sonderfall jedoch nicht.

Die gängigsten Idiome für Merge-Anfragen sind unten aufgelistet.

Einfach setzen

$connection->merge('example')
  ->key('name', $name)
  ->fields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->execute();

Im obigen Beispiel geben wir an, dass die Anfrage auf die Tabelle „example“ abzielt. Dann geben wir ein Schlüssel-Feld 'name' mit dem Wert $name an. Danach definieren wir ein Array von Werten, die gesetzt werden sollen.

Existiert bereits eine Zeile, in der das Feld „name“ den Wert $name hat, werden die Felder field1 und field2 in dieser bestehenden Zeile auf die entsprechenden Werte gesetzt. Existiert eine solche Zeile nicht, wird eine solche angelegt, in der name den Wert $name hat, field1 den Wert $value1 und field2 den Wert $value2. Somit ist das Endergebnis der Anfrage am Ende immer gleich, unabhängig davon, ob die Zeile bereits existierte oder nicht.

Bedingte Zuweisung

In manchen Fällen ist es nötig, Werte unterschiedlich zu setzen, je nachdem, ob der Datensatz, definiert durch die key()-Felder, bereits existiert. Dafür gibt es zwei Möglichkeiten.

$connection->merge('example')
  ->insertFields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->updateFields([
    'field1' => $alternate1,
  ])
  ->key('name', $name)
  ->execute();

Das obige Beispiel verhält sich wie das erste, mit dem Unterschied, dass wenn der Datensatz bereits existiert und wir ihn aktualisieren, für field1 der Wert $alternate1 gesetzt wird anstelle von $value1, und field2 bleibt dabei unverändert. Die Methode updateFields() akzeptiert entweder ein assoziatives Array von Werten oder zwei parallele numerische Arrays, eines mit Feldnamen und eines mit Werten, die in der gleichen Reihenfolge sein müssen.

$connection->merge('example')
  ->key('name', $name)
  ->fields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->expression('field1', 'field1 + :inc', [':inc' => 1])
  ->execute();

In diesem Beispiel, falls der Datensatz bereits existiert, wird für field1 sein aktueller Wert plus 1 gesetzt. Das ist besonders nützlich für „Zähler-Anfragen“, wenn Sie in der Datenbank einen Zähler bei jedem Ereignis inkrementieren möchten. field2 erhält dabei den gleichen Wert, egal ob der Datensatz existiert oder nicht.

Beachten Sie, dass expression() mehrmals aufgerufen werden kann, je einmal für jedes Feld, das bei bestehendem Datensatz auf einen Ausdruck gesetzt werden soll. Der erste Parameter ist das Feld, der zweite ein SQL-Fragment, das den Ausdruck beschreibt, auf den das Feld gesetzt werden soll, und der optionale dritte Parameter ist ein Array von Platzhalterwerten für den Ausdruck.

Es ist auch nicht notwendig, dass ein Feld, das in expression() verwendet wird, zuvor in fields() angegeben wurde.

Angesichts der oben beschriebenen API ist es möglich, Anfragen zu definieren, die logisch keinen Sinn ergeben, z.B. wenn für ein Feld sowohl Ignorieren als auch Setzen über Ausdruck angegeben sind, falls der Datensatz bereits existiert. Um Fehler zu minimieren, gelten folgende Regeln:

  • Wenn für ein Feld expression() gesetzt ist, hat dies Vorrang vor updateFields().
  • Wenn Werte in updateFields() angegeben sind, werden nur diese Felder beim Update verändert. Felder, die nicht in updateFields() genannt sind, bleiben unberührt.

Beachten Sie, dass es dennoch möglich ist, sinnlose Anfragen zu definieren. Der Entwickler sollte sicherstellen, dass keine unsinnige Anfrage angegeben wird, da das Verhalten in diesem Fall nicht definiert ist.

Source URL:

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.