Frage

Ich verwende die PHP Doctrine ORM meine Abfragen zu erstellen. Allerdings kann ich nicht ganz auf Figur scheinen, wie die folgende WHERE-Klausel DQL (Doctrine Query Language) schreiben:

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

Wie kann ich angeben, wo die Klammern gehen?

Was ich zur Zeit in meinem PHP-Code habe, ist dies:

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

Aber das erzeugt so etwas wie

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

die aufgrund der Reihenfolge der Operationen, nicht die gewünschten Ergebnisse zurück.

Auch gibt es einen Unterschied zwischen dem "wo", "UndWo" und "addWhere" Methoden?

UPDATE Ok, scheint es, wie Sie nicht komplexe Abfragen tun können DQL verwenden, also habe ich versucht, die SQL manuell zu schreiben und die UndWo () -Methode hinzufügen verwenden. Aber ich bin mit WHERE..IN und Lehre scheint meine umschließenden Klammern werden Strippen aus:

$q->andWhere("(category1 IN $subcategory_in_clause
            OR category2 IN $subcategory_in_clause 
            OR category3 IN $subcategory_in_clause)");
War es hilfreich?

Lösung

Aus meiner Erfahrung, jede komplexe where Funktion in Klammern gruppiert ist (ich verwende Lehre 1.2.1).

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

erzeugt folgende SQL:

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

Andere Tipps

Der richtige Weg, dies zu tun, kann unter Lehre 2 - Query Builder bedingte Abfragen ... Wenn Aussagen wie @Jekis bemerkt?. Hier ist, wie die Expression Builder zu verwenden, um diese wie in dem @ anushr Beispiel zu lösen.

$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);

Wie es scheint, wie Sie nicht komplexe Abfragen mit DQL tun können, schrieb ich die folgende SQL zum UndWo () Methode übergeben:

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

Beachten Sie die "AND TRUE", einen Hack, so dass der Parser die äußeren Klammern nicht außer Acht lassen würde.


:

UndWo können wie folgt zusammengefasst werden Zuvor Hinzugefügt Bedingung (en) Aware WHERE Statement

Sie können sicher verwenden UndWo Inplace von mit . (Es stellt einen sehr kleinen Overhead, die in der zweiten Liste Artikel unten angegeben ist.)

Die Umsetzung der UndWo ist: (Lehre 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);
}

, die als gelesen werden können,

  1. Prozessparameter
  2. append und Aussage mit Teil der Abfrage, , wenn eine andere, wo Anweisung hinzugefügt wurde, bevor
  3. anhängen Bedingung

Was den Unterschied zwischen den, undwobei und addwhere, ich glaube nicht, dass es ein signifikanter Unterschied von dem letzten Mal, wenn ich die Quelle lesen. Ich möchte Sie ermutigen, die Lehre Quelle zu lesen, aber. Es ist wirklich einfach, und hilft füllt die Löcher in der Dokumentation (es gibt viele). Wie für komplexe, wo Aussagen habe ich das selbst gewundert, aber noch keine Notwendigkeit für sie noch hatte.

Nach meiner Erfahrung, ich habe manchmal einen Unterschied zwischen gesehen:

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

und

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

Die erste Anweisung ist auf drei Zeilen geschrieben, die zweite, auf nur einen. Ich habe es nicht glauben, aber es gibt einen Unterschied!

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

Sie so nett sein, diese Variante zu versuchen, nicht sicher, ob es funktioniert, aber einen Versuch wert

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top