Consultas Estáticas
Las consultas SELECT más comunes en Drupal son consultas estáticas que usan el método query() del objeto de conexión a la base de datos.
Las consultas estáticas se envían a la base de datos casi literalmente.
Ejemplo:
$database = \Drupal::database(); $query = $database->query("SELECT id, example FROM {mytable}"); $result = $query->fetchAll();
Sólo las consultas SELECT muy simples deben usar el método estático query(). Debes usar una consulta dinámica si necesitas consultas más complejas, generación dinámica de consultas o variabilidad.
No uses esta función para consultas simples INSERT, UPDATE o DELETE. Estas deben manejarse a través de insert(), update() y delete() respectivamente. Para consultas DELETE más complejas que involucren varias tablas, consulta Consultas DELETE complejas.
Argumentos
El método query() del objeto de conexión a la base de datos acepta tres argumentos:
- $query: la consulta que se ejecutará. Usa marcadores de posición y encierra todos los nombres de tabla entre llaves si es necesario.
- $args: un arreglo de valores para reemplazar los marcadores de posición en la consulta.
- $options: un arreglo de opciones para controlar el comportamiento de la consulta (opcional).
Prefijo del nombre de la tabla
En consultas estáticas, todos los nombres de tabla deben ir entre llaves {...}.
Encerrar los nombres de tabla entre llaves marca estos nombres para que el sistema de base de datos pueda anteponer un prefijo si es necesario. El prefijo permite ejecutar múltiples sitios desde una misma base de datos o, en algunos casos, compartir tablas seleccionadas entre sitios. También evita filtraciones de datos entre el sitio host y los sitios de prueba.
Marcadores de posición
Los marcadores de posición indican dónde se insertará un valor literal en la consulta para su ejecución. Al separarlos de la consulta, permitimos que la base de datos distinga entre la sintaxis SQL y los valores proporcionados por el usuario, evitando ataques de inyección SQL.
$query = $database->query("SELECT id, example FROM {mytable} WHERE created > :created", [ ':created' => REQUEST_TIME - 3600, ]);
El código anterior selecciona todos los IDs y ejemplos de mytable creados en la última hora (3600 segundos). El marcador :created será reemplazado dinámicamente por el valor REQUEST_TIME - 3600 al ejecutar la consulta.
La consulta puede tener cualquier cantidad de marcadores de posición, pero todos deben tener nombres únicos, incluso si tienen el mismo valor. Según el caso, el arreglo de marcadores puede definirse en línea (como arriba) o prepararse antes y luego pasarse. El orden del arreglo no importa.
Los marcadores que comienzan con "db_" están reservados para uso interno del sistema y nunca deben especificarse explícitamente.
Ten en cuenta que los marcadores no deben escaparse ni encerrarse entre comillas, sin importar su tipo. Como se pasan por separado al servidor de base de datos, éste puede distinguir entre la cadena de la consulta y el valor.
// INCORRECTO (comillas alrededor del marcador :type) $result = $database->query("SELECT example FROM {mytable} WHERE type = ':type'", [ ':type' => 'mytype', ]); // CORRECTO (sin comillas alrededor del marcador :type) $result = $database->query("SELECT example FROM {mytable} WHERE type = :type", [ ':type' => 'mytype', ]);
No se pueden usar marcadores de posición para nombres de columnas o tablas. Si estos provienen de entradas inseguras, deben escaparse usando $database->escapeTable().
Marcadores de posición en arreglo
La capa de base de datos de Drupal añade una función adicional para los marcadores. Si el valor pasado a un marcador es un arreglo, se expandirá automáticamente en una lista separada por comas, acorde con el marcador correspondiente. Esto evita que los desarrolladores tengan que contar cuántos marcadores necesitan.
El siguiente ejemplo aclara este comportamiento:
$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids[])", [':ids[]' => [13, 42, 144]]);
Las siguientes dos sentencias son equivalentes a la anterior:
$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids_1, :ids_2, :ids_3)", [ ':ids_1' => 13, ':ids_2' => 42, ':ids_3' => 144, ]); $result = $database->query("SELECT * FROM {mytable} WHERE id IN (13, 42, 144)");
Opciones de la consulta
El tercer parámetro del método query() del objeto de conexión a la base de datos es un arreglo de opciones que definen el comportamiento de la consulta. Normalmente sólo dos directivas se usan en la mayoría de las consultas; las demás son para uso interno.
La clave "target" indica el objetivo de la consulta. Si no se especifica, se usa por defecto "default". Actualmente el único otro valor válido es "replica", para indicar que la consulta debe ejecutarse en un servidor réplica si existe.
La clave "fetch" indica cómo se obtienen los registros devueltos por la consulta. Valores válidos: PDO::FETCH_OBJ, PDO::FETCH_ASSOC, PDO::FETCH_NUM, PDO::FETCH_BOTH o el nombre de una clase. Si se especifica una cadena, cada registro se extrae en un nuevo objeto de esa clase. Los demás valores se comportan según PDO y devuelven registros como objeto stdClass, arreglo asociativo, arreglo numérico o arreglo con claves numéricas y asociativas respectivamente. Consulta http://php.net/manual/en/pdostatement.fetch.php. El valor por defecto es PDO::FETCH_OBJ, recomendado para mantener consistencia salvo que exista razón especial para otro.
El siguiente ejemplo ejecuta la consulta en el servidor réplica si está disponible y obtiene los registros como arreglo asociativo.
$result = $database->query("SELECT id, example FROM {mytable}", [], [ 'target' => 'replica', 'fetch' => PDO::FETCH_ASSOC, ]);
El objeto resultado retornado por query() puede usarse para obtener cada fila y luego cada columna. En el siguiente ejemplo, la variable $result contiene todas las filas devueltas y luego se extrae cada fila individual en $row usando fetchAssoc():
$sql = "SELECT name, quantity FROM goods WHERE vid = :vid"; $result = $database->query($sql, [':vid' => $vid]); if ($result) { while ($row = $result->fetchAssoc()) { // Hacer algo con: // $row['name'] // $row['quantity'] } }
Consultas DELETE complejas
Usar una consulta estática es una forma simple y compacta de expresar una eliminación que borra registros de múltiples tablas en una sola sentencia.
Ejemplo:
$database = \Drupal::database(); $database->query("DELETE {table1}, {table2} FROM {table1} INNER JOIN {table2} ON {table1}.id = {table2}.id WHERE {table1}.id=:recno", [":recno" => 2]);
(Esto elimina la fila tanto de table1 como de table2)
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.