logo

Extra Block Types (EBT) - Nuova esperienza con Layout Builder❗

Extra Block Types (EBT) - tipi di blocchi stilizzati e personalizzabili: Slideshows, Tabs, Cards, Accordion e molti altri. Impostazioni integrate per sfondo, DOM Box, plugin javascript. Vivi oggi il futuro della costruzione dei layout.

Demo moduli EBT Scarica moduli EBT

❗Extra Paragraph Types (EPT) - Nuova esperienza con Paragraphs

Extra Paragraph Types (EPT) - insieme di moduli basati su paragrafi in modo analogo.

Demo moduli EPT Scarica moduli EPT

Scorri

Lavorare con il database in Drupal 7 – Lezione 11 – Query di unione (MERGE)

14/10/2025, by Ivan

Le query di unione (MERGE) sono un tipo speciale di query ibrida. Sebbene la sintassi per queste query sia stata definita nello standard SQL 2003, di fatto non esistono database che supportano completamente tale sintassi. Tuttavia, la maggior parte dei database offre un’implementazione alternativa attraverso una propria sintassi specifica. Il costruttore di query di unione di Drupal astrae il concetto di merge in una struttura a oggetti, così che l’oggetto possa essere compilato in modo diverso a seconda del database utilizzato.

In generale, una query di unione è una combinazione di un’operazione di inserimento (INSERT) e di aggiornamento (UPDATE). Se la condizione specificata è soddisfatta — ad esempio, se esiste già una riga con una determinata chiave — viene eseguita una query; altrimenti, ne viene eseguita un’altra. Nella maggior parte dei casi, questo è equivalente al seguente codice:

<?php
if (db_result(db_query("SELECT COUNT(*) FROM {example} WHERE id=:id", array(':id' => $id))->fetchField())) {
  // Esegui un aggiornamento usando WHERE id = $id
}
else {
  // Esegui un inserimento, aggiungendo $id come id
}
?>

L’implementazione effettiva varia da database a database. Anche se le query di tipo MERGE sono concettualmente operazioni atomiche, potrebbero esserlo o meno a seconda del database. Ad esempio, in MySQL il merge è effettivamente atomico, ma nel codice mostrato sopra non lo sarebbe.

La forma più comune di una query di unione è la seguente:

Semplice da usare

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

In questo esempio operiamo sulla tabella example. Definiamo un campo chiave name con il valore $name e impostiamo un array di valori da inserire o aggiornare.

Se una riga con il valore $name nel campo name esiste già, i campi field1 e field2 verranno aggiornati con i valori corrispondenti. Se tale riga non esiste, verrà creata una nuova riga con name = $name, field1 = $value1 e field2 = $value2.

Impostare condizioni diverse

In alcuni casi potresti voler impostare valori diversi a seconda che il record definito da key() esista o meno. Esistono due modi per farlo.

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

Questo esempio si comporta come il precedente, ma se il record esiste già, il campo field1 verrà aggiornato con $alternate1. Se invece il record non esiste, verrà creato con field1 = $value1 e field2 = $value2. Il metodo updateFields() accetta un array associativo o due array numerici — uno per i campi e uno per i valori — che devono essere nello stesso ordine.

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

In questo esempio, se il record esiste già, il campo field1 verrà incrementato di 1. Questa funzionalità è utile per i cosiddetti “query contatori”, quando è necessario aumentare un valore ogni volta che si verifica un determinato evento. Se il record non esiste, verrà creato con i valori field1 e field2 impostati come specificato. Nota che il metodo expression() può essere chiamato più volte, una per ciascun campo, per impostare un’espressione SQL nel caso in cui il record esista già. Il primo parametro è il nome del campo, il secondo è il frammento SQL dell’espressione e il terzo (opzionale) è un array di segnaposto con i relativi valori.

Non è necessario che un campo usato in expression() sia anche presente in fields().

Aggiornamento limitato

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

Il metodo updateExcept() accetta un array di campi o un elenco di campi separati da virgola. I campi specificati in updateExcept() non verranno aggiornati se il record esiste già. Quindi, se il record con name = $name esiste, il campo field2 verrà aggiornato a $value2, mentre field1 verrà ignorato e manterrà il valore attuale. Se invece il record non esiste, field1 sarà impostato a $value1.

Priorità

L’API mostrata sopra consente di definire query che in alcuni casi potrebbero risultare incoerenti. Ad esempio, si potrebbe escludere un campo da updateExcept() e contemporaneamente definirne un’espressione in expression(). Per ridurre al minimo tali errori, si applicano le seguenti regole:

  • Se un campo ha una definizione in expression(), questa ha la priorità su update() e updateExcept().
  • Se un valore è definito in update(), l’impostazione di updateExcept() viene ignorata.
  • Se i valori sono definiti in update(), solo questi campi verranno modificati quando il record esiste già. I campi non inclusi in update() non verranno toccati.

Ricorda che è comunque possibile definire query che non abbiano molto senso logico.