Usando la cláusula IN en db_query

35

No puedo entender cómo agregar una cláusula IN en mi consulta, usando marcadores de posición.

Me gustaría que fuera algo como:

$nids = array(1, 2, 3);
$result = db_query('SELECT * FROM {node} WHERE nid IN :nids', array(':nids' => $nids));

No puedo encontrar ninguna documentación sobre esta simple tarea. ¿Cuál es la forma correcta de lograr esto?

Olof Johansson
fuente

Respuestas:

44

Te faltan los frenos.

Prueba esto:

$nids = array(1, 2, 3);
$result = db_query('SELECT * FROM {node} WHERE nid IN (:nids)', array(':nids' => $nids));

Para obtener más información, consulte http://drupal.org/node/310072 , especialmente el capítulo sobre matrices de marcadores de posición:

Matrices de marcadores de posición

La capa de base de datos de Drupal incluye una característica adicional de marcadores de posición. Si el valor pasado para un marcador de posición es una matriz, se expandirá automáticamente en una lista separada por comas al igual que el marcador de posición correspondiente. Eso significa que los desarrolladores no necesitan preocuparse por contar cuántos marcadores de posición necesitarán.

Un ejemplo debería aclarar este comportamiento:

<?php
// This code:
db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => array(13, 42, 144));

// Will get turned into this prepared statement equivalent automatically:
db_query("SELECT * FROM {node} WHERE nid IN (:nids_1, :nids_2, :nids_3)", array(
  ':nids_1' => 13, 
  ':nids_2' => 42, 
  ':nids_3' => 144,
));

// Which is equivalent to the following literal query:
db_query("SELECT * FROM {node} WHERE nid IN (13, 42, 144)");
?>
Berdir
fuente
Sabía que estaba cerca;) ¡Gracias por la respuesta y el enlace!
Olof Johansson
¿Qué pasa con las cuerdas? node_types = array('node_type_1', 'node_type_2');
Serjas
Igual, no importa.
Berdir
18

Para Drupal 8

Consulta de entidad:

$query = \Drupal::entityTypeManager()->getStorage('entity_type')->getQuery();
$query->condition('field/property', [1, 2, 3], 'IN');
$ids = $query->execute();

Consulta SQL (select), esencialmente lo mismo para otros tipos de consulta.

$query = \Drupal::database()->select('table', 't');
$query->condition('column', [1, 2, 3], 'IN');
...

Para Drupal 7

Ver la respuesta de Berdir.

Para Drupal 6

Puedes hacerlo así:

$nids = array(1, 2, 3);
$placeholders = db_placeholders($nids);
$result = db_query("SELECT * FROM {node} WHERE nid IN ($placeholders)", $nids);

Se necesita db_placeholders en Drupal 6, que creará una cadena que contenga los marcadores de posición necesarios para la matriz de valores dados. Drupal 7 maneja todo esto internamente como lo describe Berdir.

googletorp
fuente
10

Uso de la API de base de datos en Drupal 7

Así es como puede usar db_select () en lugar de db_query () para obtener los mismos resultados.

$nids = array(1, 2, 3);
$query = db_select('node', 'n')
  ->fields('n')
  ->condition('n.nid', $nids, 'IN')
  ->execute();
$nodes = $query->fetchAll();
tyler.frankenstein
fuente
1

Drupal 6 Si su matriz contiene cadenas, debe decirle a db_placeholders ()

$colours = array('red', 'yellow', 'blue');
$placeholders = db_placeholders($colours,'text');
$result = db_query("SELECT * FROM {bricks} WHERE colour IN ($placeholders)", $colours);
Peter Cook
fuente
-1

Actualización de Drupal 8.

También valido.

$nids = db_query("SELECT nid FROM node_field_data WHERE nid IN (:nids[]) AND status = 1", [
  ':nids[]' => $nids
])->fetchCol();
Chris Calip
fuente
db_queryestá en desuso y se eliminará en Drupal 9. No debería recomendarse como solución en este momento. Tampoco debe usar la base de datos directamente para consultar datos relacionados con entidades; hay API para eso
Clive
La recomendación es estrictamente la actualización de Drupal 8. La respuesta aceptada actual ya no funciona para Drupal 8, porque carece de corchetes. Para rechazar esta respuesta porque no funciona para Drupal 9, otra versión principal es falsa. Impide que los usuarios obtengan una respuesta que simplemente funciona. El sentimiento es un claro ejemplo de, Perfecto es enemigo de lo suficientemente bueno.
Chris Calip