logo

Types de blocs supplémentaires (EBT) – Nouvelle expérience de Layout Builder❗

Types de blocs supplémentaires (EBT) – types de blocs stylisés et personnalisables : diaporamas, onglets, cartes, accordéons et bien d’autres. Paramètres intégrés pour l’arrière-plan, la boîte DOM, les plugins JavaScript. Découvrez dès aujourd’hui le futur de la création de mises en page.

Démo des modules EBT Télécharger les modules EBT

❗Types de paragraphes supplémentaires (EPT) – Nouvelle expérience Paragraphes

Types de paragraphes supplémentaires (EPT) – ensemble de modules basé sur les paragraphes analogiques.

Démo des modules EPT Télécharger les modules EPT

Défilement

Travail avec la base de données dans Drupal 7 - leçon 11 - Requêtes de fusion (MERGE)

06/07/2025, by Ivan

Les requêtes de fusion sont un type spécial hybride de requêtes. Bien que la syntaxe pour ces requêtes ait été définie dans SQL 2003, en réalité aucune base de données ne supporte cette syntaxe. Cependant, la plupart des bases de données fournissent une implémentation alternative en utilisant une syntaxe spécifique. Le constructeur de requêtes de fusion dans Drupal abstrait le concept de fusion de requête dans une structure objet, de sorte que cet objet peut être compilé différemment pour chaque base de données en tenant compte de ses spécificités.

Dans un sens général, une requête de fusion est une combinaison d'une requête d'insertion et d'une requête de mise à jour. Si la condition est remplie, dans une ligne avec une clé déjà existante, alors une requête sera exécutée. Sinon, l'autre requête sera exécutée. Dans la plupart des cas, cela équivaut à :

<?php
if (db_result(db_query("SELECT COUNT(*) FROM {example} WHERE id=:id", array(':id' => $id))->fetchField())) {
  // Exécuter une mise à jour WHERE id = $id
}
else {
  // Exécuter une insertion, insérant $id pour id
}
?>

La véritable implémentation varie d'une base de données à l'autre. Notez que, même si conceptuellement les requêtes de fusion sont des opérations atomiques, elles peuvent ou non être réellement atomiques selon l'implémentation spécifique à chaque base de données. Par exemple, l'implémentation MySQL est une requête atomique, mais dans l'exemple ci-dessus ce n'est pas le cas.

La forme la plus générale d'une requête de fusion est illustrée ci-dessous :

Faites-le simplement

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

Dans l'exemple ci-dessus, nous opérons sur la table "example". Nous décrivons un champ clé 'name' avec la valeur $name. Nous décrivons également un tableau de valeurs à définir.

Si une ligne existe déjà où chaque champ 'name' a la valeur $name, alors les champs field1 et field2 seront mis à jour avec les valeurs correspondantes. Si une telle ligne n'existe pas, une nouvelle ligne sera créée où name aura la valeur $name, et field1 et field2 auront les valeurs $value1 et $value2 respectivement.

Définir des conditions

Dans certains cas, vous pouvez souhaiter définir différentes valeurs selon que l'enregistrement défini par key() existe ou non. Il y a deux façons de faire cela.

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

L'exemple ci-dessus se comporte comme le premier, sauf que si l'enregistrement existe, nous mettons à jour field1 avec la valeur $alternate1. Si l'enregistrement n'existe pas, il est créé avec les valeurs field1=$value1, field2=$value2. La méthode update() accepte soit un tableau associatif unique, soit deux tableaux indexés, l'un pour les champs et l'autre pour les valeurs, qui doivent être dans le même ordre.

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

Dans cet exemple, si l'enregistrement existe déjà, alors field1 sera incrémenté de 1. Cela est utile pour des "requêtes compteur" où vous devez incrémenter un compteur chaque fois qu'un événement survient. Cependant, si l'enregistrement n'existe pas, les champs field1 et field2 seront définis avec leurs valeurs. Notez que expression() peut être appelé plusieurs fois, une fois pour chaque champ, pour définir une expression lorsque l'enregistrement existe déjà. Le premier paramètre est le champ, le second est un fragment SQL décrivant l'expression à appliquer, et le troisième paramètre optionnel est un tableau de valeurs de remplacement à insérer dans l'expression.

Il n'est pas nécessaire que le champ utilisé dans expression() soit également défini dans fields().

Mise à jour limitée

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

La méthode updateExcept() accepte un tableau de champs ou une série de champs passés en paramètres séparés. Les champs listés dans updateExcept() ne seront pas modifiés si l'enregistrement existe déjà. Donc, si l'enregistrement name = $name existe déjà, alors le champ field2 sera mis à jour avec $value2 et field1 sera complètement ignoré et conservera sa valeur actuelle, mais si l'enregistrement n'existe pas, alors field1 sera défini avec $value1.

Priorités

L’API ci-dessus permet de définir une requête qui pourrait ne pas avoir de sens. Par exemple, si un champ est ignoré à la fois par updateExcept() et qu'une expression est définie pour ce même champ. Pour minimiser les erreurs potentielles, les règles suivantes s’appliquent :

  • Si un champ définit une expression(), elle a une priorité plus élevée que update() et updateExcept().
  • Si une valeur est définie dans update(), elle remplace celle dans updateExcept().
  • Si des valeurs sont définies dans update(), seuls ces champs seront modifiés si l'enregistrement existe déjà. Les champs non définis dans update() ne seront pas modifiés.

Notez qu'il est possible de définir des requêtes qui n'auront pas de sens.