Où les clauses complexes utilisent la Doctrine PHP ORM

j'utilise L'ORM de Doctrine PHP pour construire mes requêtes. Cependant, je ne peux pas tout à fait comprendre comment écrire la clause suivante Où utiliser DQL (Doctrine Query Language):

WHERE name='ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X') 
AND price > 10

Comment puis-je préciser où vont les parenthèses?

ce que j'ai actuellement dans mon code PHP est ceci:

->where('name = ?', 'ABC')
->andWhere('category1 = ?', 'X')
->orWhere('category2 = ?', 'X')
->orWhere('category3 = ?', 'X')
->andWhere('price > ?', 10)

mais cela produit quelque chose comme

WHERE name='ABC' AND category1 = 'X' OR category2 = 'X' OR category3 = 'X' 
AND price > 10

qui, en raison de l'ordre des opérations, ne retourne pas les résultats escomptés.

Existe-t-il également une différence entre les méthodes" où"," et où "et" addWhere"?

mise à JOUR Ok, il semble que vous ne pouvez pas faire de requêtes complexes en utilisant DQL, donc j'ai essayé d'écrire le SQL manuellement et d'utiliser la méthode andWhere() pour l'ajouter. Cependant, J'utilise où...dans et la Doctrine semble enlever mon enclos entre parenthèses:

$q->andWhere("(category1 IN $subcategory_in_clause
            OR category2 IN $subcategory_in_clause 
            OR category3 IN $subcategory_in_clause)");
32
demandé sur Wickethewok 2009-06-26 19:04:31

6 réponses

D'après mon expérience, chaque fonction complexe where est groupée entre parenthèses (J'utilise la Doctrine 1.2.1).

$q->where('name = ?', 'ABC')
  ->andWhere('category1 = ? OR category2 = ? OR category3 = ?', array('X', 'X', 'X'))
  ->andWhere('price < ?', 10)

produit le code SQL suivant:

WHERE name = 'ABC' 
  AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
  AND price < 10
64
répondu anushr 2010-06-19 11:27:27

la bonne façon de faire cela peut être trouvée à doctrine 2 - requêtes conditionnelles builder... Si les déclarations? comme noté par @Jekis. Voici comment utiliser l'expression builder pour résoudre ce problème comme dans l'exemple de @anushr.

$qb->where($qb->expr()->eq('name', ':name'))
  ->andWhere(
    $qb->expr()->orX(
      $qb->expr()->eq('category1', ':category1'),
      $qb->expr()->eq('category2', ':category2'),
      $qb->expr()->eq('category3', ':category3')
  )
  ->andWhere($qb->expr()->lt('price', ':price')
  ->setParameter('name', 'ABC')
  ->setParameter('category1', 'X')
  ->setParameter('category2', 'X')
  ->setParameter('category3', 'X')
  ->setParameter('price', 10);
12
répondu David Baucum 2017-05-09 15:19:16

comme il semble que vous ne pouvez pas faire de requêtes complexes en utilisant DQL, J'ai écrit le SQL suivant pour passer à la méthode andWhere ():

$q->andWhere("(category1 IN $subcategory_in_clause
OR category2 IN $subcategory_in_clause 
OR category3 IN $subcategory_in_clause) AND TRUE");

Notez le" and TRUE", un hack pour que l'analyseur n'ignore pas les parenthèses extérieures.

1
répondu Wickethewok 2009-06-26 20:59:32

et où peut se résumer comme suit::

Condition(s) précédemment ajoutée (s) Aware WHERE Statement

vous pouvez utiliser en toute sécurité et partout au lieu de . (il introduit un très petit plafond, qui est indiqué ci-dessous dans le point de la deuxième liste.)

La mise en œuvre de la et où est la suivante: (Doctrine 1.2.3)

public function andWhere($where, $params = array())
{
    if (is_array($params)) {
        $this->_params['where'] = array_merge($this->_params['where'], $params);
    } else {
        $this->_params['where'][] = $params;
    }

    if ($this->_hasDqlQueryPart('where')) {
        $this->_addDqlQueryPart('where', 'AND', true);
    }

    return $this->_addDqlQueryPart('where', $where, true);
}

, qui se lit comme suit:,

  1. paramètres du procédé
  2. ajouter et ajouter partie de la requête, si un autre où la déclaration a été ajoutée avant
  3. annexe condition
1
répondu Lashae 2011-02-05 12:34:38

quant à la différence entre où, et où, et addwhere, Je ne crois pas qu'il y ait une différence significative par rapport à la dernière fois que j'ai lu la source. Je vous encourage cependant à lire la source de la Doctrine. C'est très simple, et permet remplit les trous dans la documentation (ils sont nombreux). En ce qui concerne les déclarations complexes, je me suis posé la question moi-même, mais je n'en ai pas encore eu besoin.

0
répondu Bob Gettys 2009-06-26 15:09:21

d'après mon expérience, j'ai parfois vu une différence entre:

$q->andWhere("(category1 IN $subcategory_in_clause
            OR category2 IN $subcategory_in_clause 
            OR category3 IN $subcategory_in_clause)");

et

$q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)");

la première déclaration est écrite sur 3 lignes, la seconde, sur une seule. Je n'y croyais pas, mais il y a une différence !

0
répondu baboush 2014-03-05 09:58:01