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 4 – Query dinamiche (SELECT)

14/10/2025, by Ivan

Probabilmente siamo arrivati alla parte più interessante del Database API di Drupal: le query dinamiche. Si chiamano così perché Drupal costruisce dinamicamente la stringa della query. Tutte le query di inserimento, aggiornamento, eliminazione o unione possono essere dinamiche. Le query di selezione possono essere sia dinamiche che statiche, ma è consigliato usare sempre le query dinamiche anche per le SELECT.

Tutte le query dinamiche vengono create come oggetti query, ai quali possiamo aggiungere condizioni e parametri quando necessario. Come nelle query statiche, la maggior parte dei casi utilizza un procedural wrapper. Tutti i parametri successivi possono essere aggiunti direttamente all’oggetto query.

Query di selezione db_select()

Le query di selezione dinamiche iniziano con la funzione db_select(), ad esempio:

<?php
$query = db_select('node', 'n', $options);
?>

In questo esempio 'node' è la tabella a cui ci riferiamo (l’equivalente della clausola FROM in SQL). Non è necessario racchiudere il nome della tabella tra parentesi graffe, poiché il costruttore di query lo farà automaticamente. Il secondo parametro è l’alias della tabella. Se non viene fornito, Drupal userà il nome della tabella stessa. Il parametro $options è facoltativo e ha la stessa struttura di quello usato nelle query statiche.

Le query di selezione dinamiche possono essere molto semplici o estremamente complesse. Vedremo i principi fondamentali per comprenderne il funzionamento, ma le loro possibilità sono molto ampie.

Esempio di db_select()

Di seguito un esempio semplice di query di selezione sulla tabella degli utenti. Più avanti vedremo come utilizzare i join per costruire query più complesse.

<?php
$query = db_select('users', 'u');

$query
  ->condition('u.uid', 0, '<>')
  ->fields('u', array('uid', 'name', 'status', 'created', 'access'))
  ->range(0, 50);

$result = $query->execute();
?>

Questo esempio equivale alla seguente query SQL:

SELECT uid, name, status, created, access FROM {users} u WHERE uid <> 0 LIMIT 50 OFFSET 0;

Join (INNER, LEFT, RIGHT)

Per unire altre tabelle alla query si utilizzano i metodi join(), innerJoin(), leftJoin() o rightJoin(), come nell’esempio seguente:

<?php
$table_alias = $query->join('user', 'u', 'n.uid = u.uid AND u.uid = :uid', array(':uid' => 5));
?>

Questo aggiunge un INNER JOIN (tipo predefinito) con la tabella “user”, alias “u”. La condizione ON è “n.uid = u.uid AND u.uid = :uid”, dove il segnaposto :uid viene sostituito con 5. I segnaposti proteggono la query da SQL injection, quindi non bisogna mai concatenare valori direttamente nella stringa SQL.

Il valore restituito dal metodo join() è l’alias effettivo della tabella, che Drupal rinominerà automaticamente se necessario per evitare conflitti.

È anche possibile eseguire join con sottoquery:

<?php
$myselect = db_select('mytable')
  ->fields('mytable')
  ->condition('myfield', 'myvalue');
$alias = $query->join($myselect, 'myalias', 'n.nid = myalias.nid');
?>

Campi (fields, addField)

Per aggiungere un campo alla query si usa addField():

<?php
$title_field = $query->addField('n', 'title', 'my_title');
?>

Questo aggiunge il campo “title” dalla tabella con alias “n” e lo rinomina “my_title”. Se l’alias non è definito, Drupal ne genera uno automaticamente (es. “title” o “n_title”).

Per selezionare più campi si possono chiamare più volte addField() o usare fields():

<?php
$query->fields('n', array('nid', 'title', 'created', 'uid'));
?>

Questo equivale a chiamare addField() quattro volte. Se si chiama fields() senza elencare campi, il risultato sarà equivalente a SELECT n.*.

DISTINCT

Per rimuovere duplicati dai risultati, si usa distinct():

<?php
$query->distinct();
?>

Attenzione: DISTINCT può ridurre le prestazioni, quindi usarlo solo se necessario.

Espressioni (addExpression)

Il costruttore di query consente anche di aggiungere espressioni SQL, ad esempio funzioni di aggregazione o calcoli:

<?php
$count_alias = $query->addExpression('COUNT(uid)', 'uid_count');
$count_alias = $query->addExpression('created - :offset', 'uid_count', array(':offset' => 3600));
?>

ORDER BY

Per ordinare i risultati, usa orderBy():

<?php
$query->orderBy('title', 'DESC');
?>

Il secondo parametro può essere “ASC” o “DESC” (ASC è il valore predefinito). È possibile aggiungere più ordinamenti chiamando più volte orderBy().

Ordine casuale (orderRandom)

Per ottenere risultati in ordine casuale, usa:

<?php
$query->orderRandom();
?>

Può essere combinato con orderBy().

GROUP BY

Per raggruppare i risultati per campo:

<?php
$query->groupBy('uid');
?>

Limitazioni (range)

Per limitare il numero di record restituiti:

<?php
$query->range(5, 10);
?>

Restituisce 10 record a partire dal sesto (l’indice parte da 0).

Estensioni per ordinamento tabellare (extend)

Drupal fornisce l’estensione TableSort per aggiungere funzionalità di ordinamento alle tabelle:

<?php
$query = $query
  ->extend('TableSort')
  ->orderByHeader($header);
?>

Condizioni (condition)

Le condizioni si aggiungono con condition() o where() per la clausola WHERE, e havingCondition() o having() per HAVING. Gli operatori funzionano in modo simile tra loro.

Esecuzione (execute)

Per eseguire la query si chiama execute():

<?php
$result = $query->execute();
?>

Il risultato può essere gestito con un ciclo:

<?php
foreach ($result as $record) {
  // Elaborazione di ogni record
}
?>

Conteggio risultati

Per ottenere il numero totale di record, si può usare countQuery():

<?php
$num_rows = $query->countQuery()->execute()->fetchField();
?>

Debug

Per visualizzare la query SQL generata, usa:

<?php
print_r($query->__toString());
?>