Verwendung der IN-Klausel in db_query

35

Ich kann nicht herausfinden, wie ich eine IN-Klausel mit Platzhaltern in meine Abfrage einfügen kann.

Ich möchte, dass es so aussieht wie:

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

Ich kann keine Dokumentation zu dieser einfachen Aufgabe finden. Was ist der richtige Weg, um dies zu erreichen?

Olof Johansson
quelle

Antworten:

44

Sie vermissen die Klammern.

Versuche dies:

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

Weitere Informationen finden Sie unter http://drupal.org/node/310072 , insbesondere im Kapitel zu Placeholder-Arrays:

Platzhalter-Arrays

Die Datenbankebene von Drupal enthält eine zusätzliche Funktion für Platzhalter. Wenn der für einen Platzhalter übergebene Wert ein Array ist, wird er ebenso wie der entsprechende Platzhalter automatisch zu einer durch Kommas getrennten Liste erweitert. Das bedeutet, dass sich Entwickler keine Gedanken darüber machen müssen, wie viele Platzhalter sie benötigen.

Ein Beispiel soll dieses Verhalten verdeutlichen:

<?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
quelle
Ich wusste, dass ich nah dran war;) Danke für die Antwort und den Link!
Olof Johansson
Was ist mit den Saiten? node_types = array('node_type_1', 'node_type_2');
Serjas
Gleich, egal.
Berdir
18

Für Drupal 8

Entitätsabfrage:

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

SQL-Abfrage (Auswahl), im Wesentlichen gleich für andere Abfragetypen.

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

Für Drupal 7

Siehe Berdir's Antwort.

Für Drupal 6

Du kannst es so machen:

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

In Drupal 6 wird db_placeholders benötigt, wodurch ein String erstellt wird, der die Platzhalter enthält, die für das angegebene Array von Werten benötigt werden. Drupal 7 erledigt dies alles intern wie Berdir beschreibt.

googletorp
quelle
10

Verwenden der Datenbank-API in Drupal 7

So können Sie db_select () anstelle von db_query () für dieselben Ergebnisse verwenden.

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

Drupal 6 Wenn Ihr Array Strings enthält, müssen Sie db_placeholders () mitteilen

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

Drupal 8 Update.

Auch gültig.

$nids = db_query("SELECT nid FROM node_field_data WHERE nid IN (:nids[]) AND status = 1", [
  ':nids[]' => $nids
])->fetchCol();
Chris Calip
quelle
db_queryist veraltet und wird in Drupal 9 entfernt. Es sollte an dieser Stelle nicht als Lösung empfohlen werden. Sie sollten die Datenbank auch nicht direkt zum Abfragen von Daten verwenden, die sich auf Entitäten beziehen. Dafür gibt es APIs
Clive
Die Empfehlung ist streng Drupal 8 Update. Die aktuell akzeptierte Antwort funktioniert nicht mehr für Drupal 8, da es keine eckige Klammer gibt. Diese Antwort abzulehnen, da sie für Drupal 9 nicht funktioniert, ist eine andere Hauptversion unaufrichtig. Es verhindert, dass Benutzer eine Antwort erhalten, die einfach funktioniert. Das Gefühl ist ein klares Beispiel dafür, dass Perfekt der Feind des Guten ist.
Chris Calip