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

Einfügeanfragen sollten immer mit einem Query-Builder-Objekt verwendet werden. In einigen Datenbanken ist eine spezielle Behandlung von LOB-Feldern (Large OBject, z.B. TEXT in MySQL) und BLOB (Binary Large OBject) erforderlich, weshalb eine Abstraktionsebene notwendig ist, damit einzelne Datenbanktreiber jede spezielle Behandlung implementieren können, die sie benötigen.

Einfügeanfragen werden mit der Methode insert() wie folgt gestartet:

$query = $connection->insert('mytable', $options);

Dies erzeugt ein Insert-Query-Objekt, das eine oder mehrere Datensätze in die Tabelle mytable einfügt. Beachten Sie, dass keine geschweiften Klammern für den Tabellennamen benötigt werden, da der Query-Builder dies automatisch behandelt.

Das Insert-Query-Objekt verwendet ein flüssiges API. Das bedeutet, dass alle Methoden (außer execute()) das Query-Objekt selbst zurückgeben, sodass Methodenaufrufe verketten werden können. In vielen Fällen muss das Query-Objekt daher nicht einmal in einer Variable gespeichert werden.

Das Insert-Query-Objekt unterstützt mehrere unterschiedliche Anwendungsmodelle, um verschiedenen Anforderungen gerecht zu werden. Im Allgemeinen besteht der Arbeitsablauf darin, die Felder anzugeben, in die eingefügt wird, die Werte für diese Felder zu definieren und die Anfrage auszuführen. Die am häufigsten empfohlenen Anwendungsmodelle sind unten aufgeführt.

Kompakte Form

Die bevorzugte Form für die meisten Einfügeanfragen ist die kompakte Form:

$result = $connection->insert('mytable')
  ->fields([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])
  ->execute();

Dies entspricht der folgenden Abfrage:

INSERT INTO {mytable} (title, uid, created) VALUES ('Example', 1, 1221717405);

Der obige Code fasst die wichtigsten Schritte des Einfügevorgangs zusammen.

$connection->insert('mytable')

Diese Zeile erzeugt ein neues Insert-Query-Objekt für die Tabelle mytable.

  ->fields([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])

Die Methode fields() akzeptiert verschiedene Parameterformen, am häufigsten wird ein assoziatives Array verwendet. Die Schlüssel des Arrays sind die Tabellenspalten, in die eingefügt werden soll, die Werte sind die einzufügenden Werte. Dies führt zu genau einer Insert-Anfrage für die angegebene Tabelle.

 ->execute();

Die Methode execute() führt die Anfrage aus. Ohne Aufruf von execute() wird die Anfrage nicht ausgeführt.

Im Gegensatz zu anderen Methoden des Insert-Query-Objekts, die das Query-Objekt selbst zurückgeben, gibt execute() den Wert des Auto-Increment-Feldes (Sequenztyp in hook_schema()) zurück, der durch die Einfügeanfrage gefüllt wurde, sofern vorhanden. Deshalb wird der Rückgabewert in obigem Beispiel der Variablen $result zugewiesen. Wenn kein Auto-Increment-Feld existiert, ist der Rückgabewert von execute() undefiniert und sollte nicht verwendet werden.

Dies ist in der Regel die bevorzugte Form für Einfügeanfragen.

Ausführlichere Form

$result = $connection->insert('mytable')
  ->fields(['title', 'uid', 'created'])
  ->values([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])
  ->execute();

Dies ist eine etwas ausführlichere Variante der vorherigen Anfrage und ergibt exakt dasselbe Resultat.

  ->fields(['title', 'uid', 'created'])

Wenn fields() mit einem indexierten Array statt einem assoziativen Array aufgerufen wird, werden nur die Felder (Datenbankspalten) gesetzt, die in der Abfrage verwendet werden sollen, ohne Werte zu definieren. Das ist nützlich für mehrstufige Anfragen.

  ->values([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])

Dieser Methodenaufruf definiert ein assoziatives Array mit Feldnamen und den einzufügenden Werten. values() kann auch ein indexiertes Array akzeptieren, dann muss die Reihenfolge der Werte mit der Reihenfolge der Felder in fields() übereinstimmen. Für die Lesbarkeit wird meist das assoziative Array bevorzugt.

Diese Form wird seltener verwendet, da die kompakte Form meist ausreichend ist. Der einzige Grund, fields() und values() zu trennen, ist meist die Ausführung von mehrstufigen Anfragen.

Mehrfache Inserts

Das Insert-Query-Objekt kann auch mehrere Wertsets aufnehmen. Das heißt, values() kann mehrmals aufgerufen werden, um mehrere Insert-Anweisungen in die Warteschlange zu stellen. Wie genau das umgesetzt wird, hängt von der Datenbank ab. Die meisten Datenbanken führen mehrere Insert-Statements zusammen in einer Transaktion aus, um Datenintegrität und Geschwindigkeit zu erhöhen. In MySQL wird die mehrwertige Insert-Syntax verwendet.

$values = [
  [
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ],
  [
    'title' => 'Example 2',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ],
  [
    'title' => 'Example 3',
    'uid' => 2,
    'created' => \Drupal::time()->getRequestTime(),
  ],
];
$query = $connection->insert('mytable')->fields(['title', 'uid', 'created']);
foreach ($values as $record) {
  $query->values($record);
}
$query->execute();

Im obigen Beispiel werden drei Insert-Statements zusammen als eine Einheit ausgeführt, wobei die effizienteste Methode des jeweiligen Datenbanktreibers verwendet wird. Beachten Sie, dass hier das Query-Objekt in einer Variablen gespeichert wurde, damit wir in der foreach-Schleife mehrfach values() aufrufen können.

Im ausführlichen Fall entspricht das Beispiel drei separaten Anfragen:

INSERT INTO {mytable} (title, uid, created) VALUES ('Example', 1, 1221717405);
INSERT INTO {mytable} (title, uid, created) VALUES ('Example 2', 1, 1221717405);
INSERT INTO {mytable} (title, uid, created) VALUES ('Example 3', 2, 1221717405);

Beachten Sie, dass bei mehrfachem Insert der Rückgabewert von execute() undefiniert ist und nicht zuverlässig verwendet werden sollte, da er je nach Datenbanktreiber variieren kann.

Einfügen per SELECT-Abfrage

Wenn Sie eine Tabelle mit Ergebnissen aus anderen Tabellen füllen möchten, müssen Sie entweder ein SELECT auf den Ausgangstabellen ausführen, die Daten in PHP durchlaufen und dann in die neue Tabelle einfügen, oder eine INSERT INTO ... SELECT FROM-Anweisung ausführen, bei der jede durch die SELECT-Abfrage zurückgegebene Zeile in die INSERT-Anfrage eingespeist wird.

Im folgenden Beispiel wollen wir eine Tabelle mytable aufbauen, die nid und den Benutzernamen aller Nodes im System enthält, die den Typ page haben.

<?php
// SELECT-Abfrage erstellen.
$query = $connection->select('node', 'n');
// Join zur users-Tabelle.
$query->join('users', 'u', 'n.uid = u.uid');
// Gewünschte Felder hinzufügen.
$query->addField('n','nid');
$query->addField('u','name');
// Bedingung hinzufügen, um nur page-Nodes zu bekommen.
$query->condition('type', 'page');

// Insert ausführen.
$connection->insert('mytable')
  ->from($query)
  ->execute();
?>

Standardwerte

Unter normalen Umständen, wenn Sie keinen Wert für ein Feld angeben und ein Standardwert im Tabellenschema definiert ist, fügt die Datenbank diesen Standardwert automatisch ein. In manchen Fällen müssen Sie der Datenbank jedoch explizit mitteilen, den Standardwert zu verwenden. Dies ist der Fall, wenn Sie beispielsweise alle Standardwerte für einen Datensatz verwenden möchten. Um der Datenbank explizit mitzuteilen, den Standardwert für ein Feld zu verwenden, gibt es die Methode useDefaults().

$query->useDefaults(['field1', 'field2']);

Diese Zeile weist die Anfrage an, für die Felder field1 und field2 den jeweiligen Standardwert zu verwenden. Beachten Sie, dass es ein Fehler ist, dasselbe Feld in useDefaults() und gleichzeitig in fields() oder values() anzugeben; dies führt zu einer Ausnahme.

$connection->insert() oder $connection->query()

Dies ist eine häufig gestellte Frage. (Siehe Kommentare auf dieser Seite.) Was ist der Unterschied zwischen insert() und query()?

Bei insert() wird jede Spalte als eigener Eintrag im Feld-Array angegeben, wodurch der Code jeden Spaltenwert säubern kann. query() nimmt eine SQL-String-Anweisung ohne Spaltenvalidierung. Wenn Sie query() mit Platzhaltern verwenden, kann der Code zwar Werte prüfen, aber Platzhalter sind optional, und es gibt keine Garantie, dass Ihr SQL keine nicht gesäuberten Werte enthält.

insert() leitet die Anfrage durch eine Reihe von Hooks, die es anderen Modulen ermöglichen, Ihre Anfragen zu prüfen und zu verändern. Dies ist der richtige Weg, um mit anderen Modulen zusammenzuarbeiten. query() ist etwas schneller, da es die Anfrage nicht durch Hooks leitet. Sie können dadurch etwas Verarbeitungszeit sparen, aber Ihr Code verhindert nicht, dass andere Module mitwirken.

insert() funktioniert besser mit anderen Datenbanken und zukünftigen Drupal-Versionen.

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.