Travail avec la base de données dans Drupal 7 - leçon 12 - Conditions des requêtes (WHERE, HAVING, LIKE)
La condition d’une requête permet de sélectionner uniquement les enregistrements répondant à certaines contraintes, par exemple les nœuds créés depuis moins de deux semaines, les termes contenant le mot "drupal", etc. En SQL, on utilise WHERE et HAVING pour définir des restrictions sur les requêtes SELECT, UPDATE, DELETE. Dans les requêtes dynamiques, un mécanisme similaire existe pour gérer ces conditions, fonctionnant de la même manière pour les trois types de requêtes : sélection, mise à jour, suppression.
Concept des expressions conditionnelles
Une condition est contenue dans une expression spéciale définissant la restriction.
Combinaison (addition, conjonction)
Chaque condition peut comprendre plusieurs expressions conditionnelles combinées ensemble. Les conditions sont combinées via les opérateurs AND (ET) et OR (OU).
Objet condition
Drupal représente chaque fragment de condition comme une instance de la classe QueryConditional. Un objet condition est donc une instance de QueryConditional.
Examinons un exemple de requête SQL :
Requête :
SELECT FROM {mytable} WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))
Expression condition :
WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))
Parties de l’expression condition :
(a = 1 AND b = 'foo' OR (c = 'bar'))
(c = 'bar')
Opérateurs de liaison des conditions :
AND, OR
Les objets des requêtes SELECT, UPDATE, DELETE sont implémentés via l’interface QueryConditionalInterface, qui fournit les interfaces pour ces trois types de requêtes. Cet objet est ensuite enveloppé dans un objet QueryConditional. La classe QueryConditional peut être appelée directement.
Chaque fragment d’expression condition est combiné avec l’opérateur AND. Un ou plusieurs fragments peuvent être combinés avec d’autres opérateurs comme OR.
API
Deux méthodes principales permettent d’utiliser les objets condition :
$query->condition($field, $value = NULL, $operator = '=')
La méthode condition()
permet de définir le champ, la valeur et l’opérateur de la condition. Elle est utilisée pour des comparaisons binaires (vrai/faux) comme =, <, >=, LIKE, etc. Si l’opérateur n’est pas défini, = est utilisé par défaut (égalité stricte). Ainsi, pour une comparaison simple, on peut écrire condition('myfield', $value)
qui se traduit par myfield = :value
, où :value est remplacé par la valeur de la variable $value.
$query->where($snippet, $args = array())
La méthode where()
est un ajout car on peut utiliser condition()
à la place. Mais where()
est fréquemment utilisée, c’est pourquoi elle a son propre method. Dans $snippet
on écrit une requête SQL classique, dans $args
un tableau des valeurs à substituer.
Il est préférable d’utiliser condition()
plutôt que where()
.
Conditions avec tableaux
Parfois, il faut créer une condition avec plusieurs valeurs. On passe un tableau au lieu d’une valeur unique. Les opérateurs SQL les plus courants dans ces cas sont IN et BETWEEN. IN sélectionne quand la valeur est exactement dans le tableau.
<?php $query->condition('myfield', array(1, 2, 3), 'IN'); // Devient : myfield IN (:db_placeholder_1, :db_placeholder_2, :db_placeholder_3) ?>
On sélectionne donc tous les enregistrements dont la valeur du champ myfield
est 1, 2 ou 3.
Pour spécifier une plage de valeurs, on utilise BETWEEN :
<?php $query->condition('myfield', array(5, 10), 'BETWEEN'); // Devient : myfield BETWEEN :db_placeholder_1 AND :db_placeholder_2 ?>
On sélectionne ainsi les enregistrements dont la valeur de myfield
est comprise entre 5 et 10.
Conditions imbriquées
Le premier paramètre de condition()
peut recevoir un autre objet condition. Une condition imbriquée peut être incluse dans une condition plus complexe, combinée avec AND et OR.
Le helper db_condition()
retourne un nouvel objet condition. Ce helper prend un paramètre indiquant le type de liaison (AND, OR, XOR). On peut aussi utiliser les helpers db_or()
, db_xor()
, db_and()
. Ces helpers suffisent généralement. Exemple :
<?php $query ->condition('field1', array(1, 2), 'IN') ->condition(db_or()->condition('field2', 5)->condition('field3', 6)); // Résultat : // (field1 IN (:db_placeholder_1, :db_placeholder_2) AND (field2 = :db_placeholder3 OR field3 = :db_placeholder_4)) ?>
Valeurs NULL
Pour vérifier des valeurs NULL, utilisez :
<?php $query->isNull('myfield'); // Résultat : (myfield IS NULL) $query->isNotNull('myfield'); // Résultat : (myfield IS NOT NULL) ?>
Ces méthodes isNull()
et isNotNull()
peuvent être combinées avec where()
et condition()
.
Notez que condition('myfield', NULL)
est obsolète, utilisez isNull()
et isNotNull()
à la place.
Sous-requêtes
La méthode condition()
supporte les sous-requêtes pour le paramètre $value
. Pour cela, on utilise un objet SelectQuery créé avec db_select()
. Au lieu d’appeler select()
, on passe cet objet en paramètre de condition()
.
Les sous-requêtes sont utiles pour des requêtes courtes et simples avec une condition sur un seul champ. Pour des requêtes plus complexes, il vaut mieux éviter et utiliser directement condition()
.
Exemples :
db_delete()
<?php db_delete('sessions') ->condition('timestamp', REQUEST_TIME - $lifetime, '<') ->execute(); // DELETE FROM {sessions} WHERE (timestamp < 1228713473) ?>
db_update()
<?php db_update('sessions') ->fields(array( 'sid' => session_id() )) ->condition('sid', $old_session_id) ->execute(); // UPDATE {sessions} SET sid = 'abcde' WHERE (sid = 'fghij'); ?>
db_delete() avec condition OR
<?php // Depuis taxonomy_term_save(): $or = db_or()->condition('tid1', 5)->condition('tid2', 6); db_delete('term_relation')->condition($or)->execute(); // DELETE FROM {term_relation} WHERE ((tid1 = 5 OR tid2 = 6)) ?>