PHP Doktrini ORM kullanarak karmaşık WHERE yan tümceleri

6 Cevap php

Benim sorguları oluşturmak için PHP Doktrini ORM kullanıyorum. Ancak, oldukça aşağıdaki yazmak için nasıl anlamaya görünüyor NEREDE DQL (Doktrini Query Language) kullanılarak fıkra edemiyor:

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

Parantez nereye nasıl belirleyebilirsiniz?

Ne ben şu anda benim PHP kodu var şudur:

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

Ama böyle bir şey üretir

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

hangi operasyonları nedeniyle sırasına, amaçlanan sonuç vermez.

Ayrıca, "nerede", "O nereye" ve "addWhere" yöntemleri arasında bir fark var mı?

UPDATE Ok, it seems like you can't do complex queries using DQL, so I've been trying to write the SQL manually and use the andWhere() method to add it. However, I'm using WHERE..IN and Doctrine seems to be stripping out my enclosing parentheses:

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

6 Cevap

Benim deneyim, her bir kompleks where function (Ben Doktrini 1.2.1 kullanıyorum) parantez içinde gruplandırılır.

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

aşağıdaki SQL üretir:

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

Ben Doctrine_Query basit bir alt sınıfı içerir benim blogda yayınlanan bir çözüm var.

http://danielfamily.com/techblog/?p=37

, Andwhere ve addwhere arasındaki fark gibi, ben kaynağını okumak son kez anlamlı bir fark olduğuna inanmıyorum. Ancak, Doktrin kaynağını okumanızı tavsiye ederim. Gerçekten basit ve (çok var) belgelerinde deliklere doldurur yardımcı olur. Ifadeleri, ben kendimi bu merak ettik ama kompleksi için henüz bunun için bir ihtiyaç olmadı.

Eğer DQL kullanarak karmaşık sorgular yapamaz gibi görünüyor, ben andwhere () yöntemine geçmek için aşağıdaki SQL yazdı:

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

Ayrıştırıcı dış parantez görmezden olmaz ki "ve gerçek", kesmek unutmayın.

andWhere can be summarized as:
Previously Added Condition(s) Aware WHERE Statement

Sen güvenle andWhere INPLACE kullanabilirsiniz where. (Bu 2 liste öğesi aşağıda belirtilmiştir çok küçük bir yük, tanıtır.)

Andwhere bir uygulamasıdır: (Doktrini 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);
}

olarak okunabilir

  1. Proses parametreleri
  2. Sorgunun where bölümünde, if another where statement was added before için AND deyimi append
  3. durumunu append

Benim durumumda, ben bazen arasındaki farkı gördük:

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

ve

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

İlk ifadesi tek üzerinde 3 satır, ikinci, yazılır. Ben inanmadım ama bir FARK VAR!