Introduzione alle query dinamiche
Le query dinamiche si riferiscono a query che vengono create dinamicamente da Drupal, invece di essere fornite come stringa SQL esplicita. Tutte le query di inserimento, aggiornamento, eliminazione e merge devono essere dinamiche. Le query di selezione possono essere sia statiche che dinamiche. Pertanto, il termine «query dinamica» solitamente si riferisce a una query Select dinamica.
Nota: nel 90% dei casi d’uso di una query select utilizzerai una query statica. Se sei in un percorso critico per le prestazioni, dovresti usare query() invece di select() per motivi di performance. Usa le query dinamiche solo se parti della query variano (ad esempio: aggiungere condizioni WHERE in base al contesto) o se devono essere modificabili.
Tutte le query create dinamicamente vengono costruite utilizzando un oggetto query, richiesto all’oggetto di connessione al database corrispondente. Come per le query statiche, nella maggior parte dei casi può essere usato un wrapper procedurale per ottenere l’oggetto query. Tuttavia, le direttive successive della query assumono la forma di metodi invocati sull’oggetto query.
Le query dinamiche di selezione vengono avviate usando il metodo select() come segue:
$database = \Drupal::database();
$query = $database->select('mytable', 'mt', $options);
In questo caso mytable è la tabella principale della query; la prima tabella dopo l’istruzione FROM. Nota che non deve essere racchiusa tra parentesi graffe. Il query builder lo gestirà automaticamente. Il secondo parametro è l’alias della tabella. Se non è specificato, viene usato il nome della tabella. L’array $options è facoltativo ed è identico all’array $options per le query statiche.
Il valore restituito da $database->select() è un oggetto di tipo Select. Quindi, il tipo del valore nella variabile $query dopo questa chiamata è un oggetto di tipo Select. Questo oggetto ha un elenco completo di metodi, come fields(), joins() e group(), che possono essere invocati per definire ulteriormente la query.
Le query dinamiche di selezione possono essere molto semplici o molto complesse. Di seguito analizzeremo le singole parti che compongono una query semplice, e nelle pagine successive vedremo metodi più complessi, come le join.
Il quadro generale
Ecco una query relativamente semplice sulla tabella users.
Supponiamo di voler creare una query dinamica equivalente alla seguente query statica:
$result = $database->query("SELECT uid, name, status, created, access FROM {users} u WHERE uid <> 0 LIMIT 50 OFFSET 0");
L’equivalente dinamico inizia così:
// Crea un oggetto di tipo Select.
$database = \Drupal::database();
$query = $database->select('users', 'u');
// Aggiungi dettagli extra a questo oggetto query: una condizione, i campi e un range.
$query->condition('u.uid', 0, '<>');
$query->fields('u', ['uid', 'name', 'status', 'created', 'access']);
$query->range(0, 50);
Spesso questo viene scritto usando una sintassi abbreviata che consente di chiamare più metodi dell’oggetto $query in catena. Quindi, il codice sopra è spesso scritto così:
// Crea un oggetto di tipo Select.
$query = $database->select('users', 'u');
// Aggiungi dettagli extra a questo oggetto query: una condizione, i campi e un range.
$query->condition('u.uid', 0, '<>')
->fields('u', ['uid', 'name', 'status', 'created', 'access'])
->range(0, 50);
In effetti, il codice può spesso essere ulteriormente semplificato concatenando la chiamata a $database->select() direttamente ai metodi dell’oggetto risultante. Questo produce:
// Crea un oggetto di tipo Select e aggiungi direttamente dettagli extra
// a questo oggetto query: una condizione, i campi e un range.
$query = $database->select('users', 'u')
->condition('u.uid', 0, '<>')
->fields('u', ['uid', 'name', 'status', 'created', 'access'])
->range(0, 50);
Questa è la forma semplificata della query usata dalla pagina di amministrazione degli utenti, che può essere usata come riferimento per ulteriori studi.
Esecuzione della query
Una volta costruita la query, chiama il metodo execute() per compilare ed eseguire la query.
$result = $query->execute();
Il metodo execute() restituirà un oggetto result set / statement, identico all’oggetto restituito dalla funzione $database->query(), e potrà essere iterato o recuperato nello stesso modo:
$result = $query->execute();
foreach ($result as $record) {
// Fare qualcosa con ciascun $record.
}
Nota. Fai attenzione quando usi i seguenti metodi con una query dinamica multicolonna:
Questi metodi attualmente richiedono indici numerici delle colonne (0, 1, 2, ecc.), e non alias di tabella. Tuttavia, al momento il query builder non garantisce un ordine preciso dei campi restituiti, quindi le colonne potrebbero non trovarsi nell’ordine previsto. In particolare, le espressioni vengono sempre aggiunte dopo i campi, anche se le aggiungi prima nella query. (Questo problema non si applica alle query statiche, che restituiscono sempre le colonne nell’ordine specificato.)
Debug
Per esaminare la query SQL che l’oggetto query utilizza in un determinato punto del suo ciclo di vita, stampa l’oggetto query. Per controllare gli argomenti, guarda l’array restituito dal metodo arguments():
echo $query; print_r($query->__toString()); print_r($query->arguments());