2011-05-12 5 views
3

동적으로 쿼리를 작성하려고합니다. 초기 상태는 괜찮습니다. 이것은 모든 쿼리에 존재해야하는 최초의 where 절입니다.진술이 추가되지 않는 곳

$qb->add('where', $qb->expr()->andx(
    $qb->expr()->eq('s.competitor', $competitor), 
    $qb->expr()->eq('s.ignored', $ignored), 
    $qb->expr()->eq('s.id', $params['s_id']), 
    $qb->expr()->eq('s.id', 'k.targetSite') 
), true); 

하지만 건물에있는 앱에서 필터링을 허용합니다. 그런 일이 발생하면 쿼리 작성기에 where 절을 추가하려고합니다. 이 줄이 코드에서 나중에 실행되면 위의 where 문을 덮어 씁니다.

$qb->add('where', $qb->expr()->like($col, $val), true); 
내가 읽고 무엇을, 3 매개 변수 $append 이전 문을 계속해야에서

,하지만 일이 아니에요. Doctrine 1.2에서는 다음과 같이 할 수 있습니다.

foreach($filter as $col => $val) { 
    $dql->addWhere($col = ?, array($val)); 
} 

QueryBuilder에 Where 절을 동적으로 추가하려면 어떻게해야합니까? 여기에 업데이트

은 전체 문장

$where = array('col' => 'k.text', 'val' => 'some word%'); 

$qb = $this->entityManager->createQueryBuilder() 
    ->select('s, sc') 
    ->from('Dashboard\Entity\Section', 'sc') 
    ->innerJoin('sc.keyword', 'k') 
    ->innerJoin('sc.site', 's') 
    ->leftJoin('k.keywordCategory', 'kc') 
    ->leftJoin('k.keywordSubCategory', 'ksc'); 

$qb->add('where', $qb->expr()->andx(
    $qb->expr()->eq('s.competitor', $competitor), 
    $qb->expr()->eq('s.ignored', $ignored), 
    $qb->expr()->eq('s.id', $params['s_id']), 
    $qb->expr()->eq('s.id', 'k.targetSite') 
), true); 

if ($where) { 
    $qb->add('where', $qb->expr()->andx(
      $qb->expr()->like($where['col'], $where['val']) 
    ), true); 
} 

$qb->addGroupBy('k.id'); 
    $qb->addGroupBy('s.id'); 

$qb->setFirstResult($params['start']) 
    ->setMaxResults($params['limit']); 

$q = $qb->getQuery(); 
echo $q->getSql(); 

되고 출력은 다음 첫 번째

SELECT s0_.id AS id0, k1_.id AS id1, k1_.name AS name2, k2_.id AS id3, k2_.name AS name4, k3_.id AS id5, k3_.text AS text6, k3_.search_vol AS search_vol7, s4_.id AS id8, s4_.sub_domain AS sub_domain9, MIN(s0_.rank) AS sclr10, MAX(s0_.created) AS sclr11 
FROM section s0_ 
INNER JOIN keyword k3_ ON s0_.k_id = k3_.id 
INNER JOIN site s4_ ON s0_.s_id = s4_.id 
LEFT JOIN keyword_category k1_ ON k3_.k_cat_id = k1_.id 
LEFT JOIN keyword_sub_category k2_ ON k3_.k_subcat_id = k2_.id 
WHERE k3_.text LIKE 'some word%' 
GROUP BY k3_.id, s4_.id LIMIT 25 OFFSET 0 

내가 그 if ($where) 절에 추가하지 않으면입니다 andx 진술이 아직 제자리에 있습니다. 그러나 동적으로 추가하려고하면 마지막 WHERE 문만 추가되고 나머지는 지워집니다. 나는 또한 이것을 덧붙여 야했다. 나는 이것 역시 시도했다.

if ($where) { 
    $qb->add('where', $qb->expr()->like($where['col'], $where['val']), true); 
} 

나는 성공적 쿼리 빌더 상태에 대해 내가 너무 유효해야 사용하려고 시도하고있는 방법을

$qb->andWhere($qb->expr()->like($where['col'], $where['val'])); 

그러나 API 문서를 사용할 수 있습니다. 내가 제대로하고 있는지, 버그인지 확인하고 싶었다.

+0

생성 된 DQL 예제 필터를 사용하여 여기에 성명을 기재하십시오. – Cobby

+0

나는 함께 일하는 전체 진술을 추가했다. – Nathan

답변

3

정상적으로 -> andWhere()를 사용할 수 있으며 문제가 해결됩니다.

Doctrine 2 QueryBuilder는 (프로그래밍 방식과 유창한 스타일을 혼합하기 때문에) 다소 혁신적인 개념이며 관련 버그가있을 수 있습니다.

코드에서 알아둬야 할 한 가지 점 : -> add ('where', ...)를 사용하는 대신 프로그래밍 방식으로 생각해야합니다. andX() 객체에 항목을 추가하고 마지막에 -> add ('where', ...) (또는 더 나은 : -> (...))

3

Looking at the code, 어디서나 문서화되었거나 버그 일 뿐이므로 작동하지 않는 것으로 보입니다.

$isMultiple = is_array($this->_dqlParts[$dqlPartName]); 
    ... 

    if ($append && $isMultiple) { 
     if (is_array($dqlPart)) { 
      $key = key($dqlPart); 

      $this->_dqlParts[$dqlPartName][$key][] = $dqlPart[$key]; 
     } else { 
      $this->_dqlParts[$dqlPartName][] = $dqlPart; 
     } 
    } else { 
     $this->_dqlParts[$dqlPartName] = ($isMultiple) ? array($dqlPart) : $dqlPart; 
    } 

그리고 절 다른 대부분의 달리 :

add()에서, 당신이 전달하는 DQL 부분은 오직 부분이 이미 쿼리 빌더의 배열로 저장되어있는 경우 추가되는 것 같다 DQL 부분은, 배열에 초기화되지 않은 : 그것은 디자인에 의해, 그러나 교리 2 상당히 새로운이 비트가 최근에 진화 한 것처럼

private $_dqlParts = array(
    'select' => array(), 
    'from' => array(), 
    'join' => array(), 
    'set'  => array(), 
    'where' => null, 
    'groupBy' => array(), 
    'having' => null, 
    'orderBy' => array() 
); 

지금이 조금 보인다. 개인적으로, 나는이 행동에 대한 버그를 제기하고 프로젝트 사람들이 말하는 것을 보았습니다. 그 밖의 것이 없다면 개선 된 문서로 끝날 수도 있습니다 ...

관련 문제