[php] WHERE IN을 교리 2와 함께 사용하는 방법

나에게 오류를 제공하는 다음 코드가 있습니다.

Message: Invalid parameter number: number of bound variables does not match number of tokens 

암호:

public function getCount($ids, $outcome)
{
    if (!is_array($ids)) {
        $ids = array($ids);
    }
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->add('select', $qb->expr()->count('r.id'))
       ->add('from', '\My\Entity\Rating r');
    if ($outcome === 'wins') {
        $qb->add('where', $qb->expr()->in('r.winner', array('?1')));
    }
    if ($outcome === 'fails') {
        $qb->add('where', $qb->expr()->in('r.loser', array('?1')));
    }
    $qb->setParameter(1, $ids);
    $query = $qb->getQuery();
    //die('q = ' . $qb);
    return $query->getSingleScalarResult();
}

데이터 (또는 $ ids) :

Array
(
    [0] => 566
    [1] => 569
    [2] => 571
)

DQL 결과 :

q = SELECT COUNT(r.id) FROM \My\Entity\Rating r WHERE r.winner IN('?1')



답변

이 문제를 조사하면서 동일한 문제를 겪고 해결책을 찾는 모든 사람에게 중요한 것을 발견했습니다.

원본 게시물에서 다음 코드 줄 :

$qb->add('where', $qb->expr()->in('r.winner', array('?1')));

명명 된 매개 변수를 배열로 래핑하면 바인딩 된 매개 변수 번호 문제가 발생합니다. 배열 래핑에서 제거하여 :

$qb->add('where', $qb->expr()->in('r.winner', '?1'));

이 문제는 수정되어야합니다. 이것은 이전 버전의 Doctrine에서 문제가되었을 수 있지만 최신 버전의 2.0에서는 수정되었습니다.


답변

이를 수행하는 가장 쉬운 방법은 배열 자체를 매개 변수로 바인딩하는 것입니다.

$queryBuilder->andWhere('r.winner IN (:ids)')
             ->setParameter('ids', $ids);


답변

완료를 위해 문자열 솔루션

$qb->andWhere('foo.field IN (:string)');
$qb->setParameter('string', array('foo', 'bar'), \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);


답변

문서에 나와있는 내용에도 불구하고이 작업을 수행하는 유일한 방법은 다음과 같습니다.

$ids = array(...); // Array of your values
$qb->add('where', $qb->expr()->in('r.winner', $ids));

http://groups.google.com/group/doctrine-dev/browse_thread/thread/fbf70837293676fb


답변

나는 그것이 오래된 게시물이라는 것을 알고 있지만 누군가에게 도움이 될 수 있습니다. ints에 대한 의견에서 묻는 질문을 해결하여 @Daniel Espendiller 답변을 투표하고 향상시킬 것입니다.

int가 제대로 작동하도록하려면 배열의 값이 int 유형인지 확인하고 전달하기 전에 int로 캐스트 할 수 있습니다.

 $qb->andWhere('foo.field IN (:ints)');
 $qb->setParameter('ints', array(1, 2),
 \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);

symfony 3.4 및 doctrine-bundle : 1.8에서 선택 / 삭제 테스트 완료


답변

나는 OP의 예제가 DQL과 쿼리 빌더를 사용하고 있다는 것을 알고 있지만 컨트롤러 또는 저장소 클래스 외부에서 수행하는 방법을 찾고 있었으므로 다른 사람들에게 도움이 될 것입니다.

다음 WHERE IN과 같이 컨트롤러에서 a 를 수행 할 수도 있습니다 .

// Symfony example
$ids    = [1, 2, 3, 4];
$repo   = $this->getDoctrine()->getRepository('AppBundle:RepoName');
$result = $repo->findBy([
    'id' => $ids
]);


답변

이를 수행하는 가장 좋은 방법은 특히 둘 이상의 조건을 추가하는 경우 다음과 같습니다.

$values = array(...); // array of your values
$qb->andWhere('where', $qb->expr()->in('r.winner', $values));

값 배열에 문자열이 포함 된 경우 따옴표가 이스케이프되기 때문에 파열 된 문자열과 함께 setParameter 메서드를 사용할 수 없습니다!