logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaring❗

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

❗Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll
01/10/2025, by Ivan

Invoegquery’s moeten altijd gebruikmaken van het query builder-object. In sommige databases is speciale verwerking vereist voor LOB-velden (Large OBject, bijvoorbeeld TEXT in MySQL) en BLOB’s (Binary Large OBject), dus is er een abstractielaag nodig zodat afzonderlijke databasedrivers eventuele speciale verwerking kunnen implementeren die zij nodig hebben.

Insert-query’s worden uitgevoerd met de methode insert() als volgt:

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

Dit maakt een insert-queryobject aan dat één of meerdere records in de tabel mytable invoegt. Merk op dat er geen accolades nodig zijn rond de tabelnaam, omdat de query builder dit automatisch afhandelt.

Het insert-queryobject gebruikt een fluent API. Dat betekent dat alle methoden (behalve execute()) hetzelfde queryobject teruggeven, zodat method chaining mogelijk is. In veel gevallen hoeft het queryobject dus helemaal niet in een variabele opgeslagen te worden.

Het insert-queryobject ondersteunt meerdere gebruikspatronen om verschillende behoeften te dekken. Over het algemeen bestaat de workflow uit het aangeven van de velden waarin de query moet invoegen, het definiëren van de waarden die ingevoegd moeten worden voor die velden en het uitvoeren van de query. De meest gebruikte en aanbevolen patronen staan hieronder.

Compacte vorm

De voorkeursvorm voor de meeste insert-query’s is de compacte vorm:

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

Dit is equivalent aan de volgende query:

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

Bovenstaand fragment combineert de belangrijkste delen van het insertproces.

$connection->insert('mytable')

Deze regel maakt een nieuw insert-queryobject aan voor de tabel mytable.

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

De methode fields() accepteert verschillende vormen van parameters, maar het meest gebruikelijk is één associatieve array. De sleutels van de array zijn de kolommen van de tabel waarin moet worden ingevoegd, en de waarden zijn de overeenkomstige waarden om in te voegen. Dit resulteert in één insert-query naar de opgegeven tabel.

 ->execute();

De methode execute() voert de query daadwerkelijk uit. Als deze methode niet wordt aangeroepen, wordt de query niet uitgevoerd.

In tegenstelling tot de andere methoden van het insert-queryobject, die het queryobject zelf teruggeven, retourneert execute() de waarde van het auto-incrementveld (een sequentietype in hook_schema()), indien aanwezig, dat door de insert-query is ingevuld. Daarom wordt de returnwaarde toegewezen aan $result in het voorbeeld hierboven. Als er geen auto-incrementveld aanwezig is, is de returnwaarde van execute() ongedefinieerd en niet betrouwbaar.

In de meeste gevallen is dit de voorkeursvorm voor insert-query’s.

Degeneratieve vorm

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

Dit is een iets uitgebreidere vorm van de vorige query en heeft exact hetzelfde resultaat.

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

Wanneer fields() wordt aangeroepen met een genummerde array in plaats van een associatieve array, stelt het alleen de velden (databasetabellenkolommen) in die in de query zullen worden gebruikt, zonder daarvoor waarden op te geven. Dit is nuttig bij meermaals invoegen later.

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

Deze methodeaanroep definieert een associatieve array van veldnamen met de waarden die in die velden ingevoegd moeten worden. De methode values() kan ook een genummerde array aannemen. Als een genummerde array wordt gebruikt, moet de volgorde van de waarden overeenkomen met de volgorde van de velden in fields(). Als een associatieve array wordt gebruikt, kan de volgorde willekeurig zijn. Meestal is de associatieve array de voorkeur vanwege de leesbaarheid.

Deze vorm van query wordt zelden gebruikt, omdat de compacte vorm meestal beter is. De enige reden om fields() en values() te scheiden, is bij meermaals invoegen.

Vorm met meerdere inserts

Het insert-queryobject kan ook meerdere sets waarden accepteren. Dat betekent dat values() meerdere keren kan worden aangeroepen om meerdere insert-statements in de wachtrij te zetten. Hoe dit precies wordt uitgevoerd, hangt af van de mogelijkheden van de gebruikte database. In de meeste databases worden meerdere insert-statements samen binnen een transactie uitgevoerd voor betere gegevensintegriteit en snelheid. In MySQL wordt de multi-value insert syntaxis gebruikt.

$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();

In het bovenstaande voorbeeld worden drie insert-statements samen uitgevoerd als één geheel, met de meest efficiënte methode voor de specifieke gebruikte databasedriver. Merk op dat we hier het queryobject in een variabele hebben opgeslagen, zodat we erdoorheen konden loopen en de methode values() herhaaldelijk konden aanroepen.

In het uitgewerkte geval is het bovenstaande voorbeeld equivalent aan de volgende drie query’s:

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

Merk op dat bij een multi-insert-query de returnwaarde van execute() ongedefinieerd is en niet betrouwbaar, aangezien dit per databasedriver kan verschillen.

Insert op basis van select-resultaten

Als je een tabel wilt vullen met resultaten uit andere tabellen, moet je ofwel een SELECT uitvoeren op de brontabellen, de data in PHP verwerken en in de nieuwe tabel invoegen, of een query INSERT INTO ... SELECT FROM uitvoeren waarbij elk record dat door de SELECT-query wordt teruggegeven in de INSERT-query wordt ingevoerd.

In dit voorbeeld willen we een tabel mytable opbouwen met nid en gebruikersnaam voor alle nodes in het systeem die van het type page zijn.

<?php
// Bouw de SELECT-query.
$query = $connection->select('node', 'n');
// Join met de users-tabel.
$query->join('users', 'u', 'n.uid = u.uid');
// Voeg de velden toe die we willen.
$query->addField('n','nid');
$query->addField('u','name');
// Voeg een conditie toe om alleen page-nodes te krijgen.
$query->condition('type', 'page');

// Voer de insert uit.
$connection->insert('mytable')
  ->from($query)
  ->execute();
?>

Standaardwaarden

Normaal gesproken, als je geen waarde opgeeft voor een bepaald veld en er een standaardwaarde is gedefinieerd in het schema van de tabel, zal de database die standaardwaarde automatisch invoegen. In sommige gevallen moet je de database echter expliciet vertellen dat ze de standaardwaarde moet gebruiken. Dit geldt bijvoorbeeld als je alle standaardwaarden voor een record wilt gebruiken. Hiervoor bestaat de methode useDefaults().

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

Deze regel geeft de query de opdracht om de standaardwaarden te gebruiken voor de velden field1 en field2. Merk op dat het een fout is om hetzelfde veld zowel in useDefaults() als in fields() of values() op te geven; dit zal een exception veroorzaken.

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

Dit is een veelgestelde vraag (zie de opmerkingen op deze pagina). Wat is het verschil tussen insert() en query()?

Bij de methode insert() wordt elke kolom afzonderlijk opgegeven als een element in de array van velden, en kan de code de waarde van elke kolom opschonen. Bij query() gebruik je een SQL-string zonder de mogelijkheid om individuele kolommen te valideren. Als je query() gebruikt met placeholders, kan de code kolomwaarden controleren, maar placeholders zijn slechts optioneel en er is geen manier om te garanderen dat je SQL geen waarden bevat die niet door placeholders zijn gegaan.

insert() stuurt de query door een set hooks, zodat andere modules je query kunnen controleren en aanpassen. Dit is de juiste manier om samen te werken met andere modules. query() is iets sneller, omdat het de query niet door hooks stuurt. Je bespaart wat verwerkingstijd, maar je code laat andere modules niet met je meewerken.

insert() werkt vaker correct met andere databases en toekomstige versies van Drupal.