web-dev-qa-db-fra.com

Comment ajouter une condition à une requête?

$acl_ids = array(1,2,3);
$database = \Drupal::database();

$result = $database
  ->query("SELECT {nid} FROM {acl_node} WHERE grant_update = :grant", 
    ['grant' => 1,])
  ->condition('acl_id', $acl_ids, 'in')
  ->fetchField();

Malheureusement, le ->condition partie ne fonctionne pas, car j'obtiens l'erreur suivante:

Appel à la méthode non définie Drupal\Core\Database\Statement :: condition ()

Quelle méthode dois-je utiliser à la place?

5
Alex

Les conditions ne sont utilisées que dans les requêtes dynamiques; la méthode query() permet d'exécuter du SQL statique.

La version dynamique serait quelque chose comme:

$result = $database
  ->select('acl_node', 'n')
  ->fields('n', ['nid'])
  ->condition('grant_update', 1)
  ->condition('acl_id', $acl_ids, 'IN')
  ->execute()
  ->fetchField();

Et la statique:

$result = $database
  ->query("SELECT nid FROM {acl_node} WHERE grant_update = :grant AND acl_id IN (:acl_ids[])", [':grant' => 1, ':acl_ids[]' => $acl_ids])
  ->fetchField();
13
Clive

Le code que vous avez écrit est équivalent au code Drupal 7 qui utilisait db_query(). Vous ne pouvez pas utiliser condition() avec l'objet renvoyé par \Drupal::database()->query(). Je changerais également votre code en deux points:

  • Vous utilisez {nid} Dans votre requête, qui est ce que vous devez utiliser lorsque nid est un nom de table, pas un nom de champ de table *
  • Vous utilisez ['grant' => 1,] Comme tableau d'arguments, alors qu'il devrait être [':grant' => 1,] Basé sur la documentation Drupal/PHP (Notez les deux-points avant le nom du champ de la table.)

Si vous ne voulez pas utiliser des fonctions qui vont être dépréciées dans Drupal 9, voyez la réponse donnée par Clive. J'ajouterai que vous pouvez toujours utiliser db_query() ou db_select() également dans Drupal 8. En fait, Drupal 8.2.x contient toujours 160 appels à db_query() et 128 appels à db_select().

$acl_ids = array(1,2,3);

$result = db_query("SELECT nid FROM {acl_node} an WHERE an.grant_update = :grant AND an.acl_id IN ( :ids[] )", [':grant' => 1, ':ids[]' => $acl_ids]);

foreach ($result AS $row) {
  // access the node ID as $row['nid'].
}

Ce code est similaire à celui utilisé dans history_read_multiple() .

  $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = :uid AND nid IN ( :nids[] )', array(
    ':uid' => \Drupal::currentUser()->id(),
    ':nids[]' => array_keys($nodes_to_read),
  ));
  foreach ($result as $row) {
    $nodes_to_read[$row->nid] = (int) $row->timestamp;
  }
  $history += $nodes_to_read;

Remarques

L'utilisation de {nid} Entraînerait l'exécution d'une requête incorrecte si Drupal utilise des préfixes pour les noms de table. Néanmoins, il n'est pas correct d'utiliser {nid} Si vous ne ne veux pas Drupal pour le modifier car il modifie un nom de table.

2
kiamlaluno