Trabajar con una base de datos en Drupal 7 - Lección 12 - Condiciones de consulta (WHERE, HAVING, LIKE)
Una condición de consulta permite seleccionar solo aquellos registros que cumplen ciertas restricciones, por ejemplo, nodos creados hace no más de dos semanas, términos que contienen la palabra "drupal", etc. En SQL usamos WHERE y HAVING para establecer condiciones en consultas SELECT, UPDATE, DELETE. En las consultas dinámicas también se implementa un mecanismo para trabajar con condiciones de consulta. Este mecanismo funciona igual para los tres tipos de consulta: selección, actualización, eliminación.
Concepto de expresiones condicionales
La condición se encuentra en una expresión especial que establece la restricción.
Combinación (conjunción)
Cada condición puede consistir en varias expresiones condicionales, que se combinan entre sí. Las condiciones se combinan usando los operadores AND (Y) y OR (O).
Objeto de condición
Drupal representa cada fragmento condicional como una instancia de la clase QueryConditional. Un objeto de condición es una instancia de QueryConditional.
Veamos un ejemplo de una consulta SQL:
Consulta:
SELECT FROM {mytable} WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))
Expresión condicional:
WHERE (a = 1 AND b = 'foo' OR (c = 'bar'))
Partes de la expresión condicional:
(a = 1 AND b = 'foo' OR (c = 'bar'))
(c = 'bar')
Operadores de combinación de condiciones:
AND, OR
Los objetos de consulta SELECT, UPDATE, DELETE se implementan mediante la interfaz QueryConditionalInterface, que proporciona interfaces para cada uno de los tres tipos de consulta. Este objeto luego se encapsula dentro del objeto QueryConditional. La clase QueryConditional puede llamarse directamente.
Cada fragmento de la condición se une mediante el operador AND. Uno o más fragmentos pueden combinarse con otros operadores como OR.
API
Hay dos métodos principales para usar todos los objetos condicionales:
$query->condition($field, $value = NULL, $operator = '=')
El método condition()
permite definir un campo, valor y operador del fragmento condicional de la consulta. Este método puede usarse para establecer condiciones de comparación binaria como =, <, >=, LIKE, etc. Si no se define el operador, se usa "=" por defecto.
$query->where($snippet, $args = array())
El método where()
es adicional, ya que puede lograrse lo mismo con condition()
, pero es comúnmente usado. El parámetro $snippet
contiene una cadena SQL y $args
es un array de valores para los marcadores de posición en $snippet
.
Se recomienda usar condition()
en lugar de where()
.
Condiciones con arrays
Algunas veces es necesario usar condiciones con múltiples valores. Para ello, se puede pasar un array como valor. Los operadores SQL más comunes en estos casos son IN y BETWEEN.
condition('myfield', array(1, 2, 3), 'IN'); // Resultado: myfield IN (:db_placeholder_1, :db_placeholder_2, :db_placeholder_3) ?>
Esto seleccionará todos los registros donde myfield
sea igual a 1, 2 o 3.
Para un rango de valores, usamos BETWEEN:
condition('myfield', array(5, 10), 'BETWEEN'); // Resultado: myfield BETWEEN :db_placeholder_1 AND :db_placeholder_2 ?>
Esto selecciona registros donde myfield
está entre 5 y 10 inclusive.
Condiciones anidadas
El primer parámetro de condition()
puede ser otro objeto de condición. Las condiciones anidadas permiten formar condiciones más complejas combinadas con operadores AND y OR.
El helper db_condition()
devuelve un nuevo objeto de condición. También existen helpers específicos como db_or()
, db_xor()
, db_and()
. Veamos un ejemplo:
condition('field1', array(1, 2), 'IN') ->condition(db_or()->condition('field2', 5)->condition('field3', 6)); // Resultado: // (field1 IN (...) AND (field2 = ... OR field3 = ...)) ?>
Valores NULL
Para comprobar valores NULL, usa los siguientes métodos:
isNull('myfield'); // Resultado: myfield IS NULL $query->isNotNull('myfield'); // Resultado: myfield IS NOT NULL ?>
Estos métodos se pueden combinar con condition()
o where()
.
Nota: condition('myfield', NULL)
está obsoleto. Usa isNull()
o isNotNull()
.
Subconsultas
El método condition()
soporta subconsultas en el parámetro $value
. Para usarlas, se crea un objeto SelectQuery
usando db_select()
, y se pasa como valor en condition()
.
Las subconsultas son útiles para condiciones simples por un campo. Para casos más complejos es mejor evitarlas y usar consultas independientes.
Veamos ejemplos:
db_delete()
condition('timestamp', REQUEST_TIME - $lifetime, '<') ->execute(); // DELETE FROM {sessions} WHERE (timestamp < 1228713473) ?>
db_update()
fields(array( 'sid' => session_id() )) ->condition('sid', $old_session_id) ->execute(); // UPDATE {sessions} SET sid = 'abcde' WHERE sid = 'fghij'; ?>
db_delete() con condiciones anidadas:
condition('tid1', 5)->condition('tid2', 6); db_delete('term_relation')->condition($or)->execute(); // DELETE FROM {term_relation} WHERE ((tid1 = 5 OR tid2 = 6)) ?>