如何使用WHERE IN与Doctrine 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') 

在研究这个问题时,我发现了一些对于遇到同样问题并寻找解决scheme的人来说都很重要。

从原来的post,下面这行代码:

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

并完成string解决scheme

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

我发现,尽pipe文档指出了什么,唯一的方法就是这样工作:

 $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

这样做的最好方法 – 特别是如果你添加多个条件 – 是:

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

如果你的数组的值包含string,你不能使用带有内爆string的setParameter方法,因为你的引号将被转义!

这是我用它的方式:

 ->where('b.status IN (:statuses)') ->setParameters([ 'customerId' => $customerId, 'storeId' => $storeId, 'statuses' => [Status::OPEN, Status::AWAITING_APPROVAL, Status::APPROVED] ]); 

在2016年发现如何做到这一点: https : //redbeardtechnologies.wordpress.com/2011/07/01/doctrine-2-dql-in-statement/

引用:

这里是如何正确地做到这一点:

 $em->createQuery(“SELECT users FROM Entities\User users WHERE users.id IN (:userids)”) ->setParameters(array('userids' => $userIds)); 

setParameters将采用一个数组并正确使用它以在“IN”语句中使用。

我更喜欢:

 $qb->andWhere($qb->expr()->in('t.user_role_id', [ User::USER_ROLE_ID_ADVERTISER, User::USER_ROLE_ID_MANAGER, ])); 

我知道OP的例子是使用DQL和查询构build器,但我偶然发现如何从控制器或存储库类以外的地方这样做,所以也许这会帮助其他人。

你也可以这样从控制器做一个WHERE IN

 // Symfony example $ids = [1, 2, 3, 4]; $repo = $this->getDoctrine()->getRepository('AppBundle:RepoName'); $result = $repo->findBy([ 'id' => $ids ]); 
 ->where($qb->expr()->in('foo.bar', ':data')) ->setParameter('participants', $data); 

也适用于:

  ->andWhere($qb->expr()->in('foo.bar', ':users')) ->setParameter('data', $data); 

我挣扎于这种情况下,我不得不对一个值的数组进行查询。

以下为我工作:

http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/dql-doctrine-query-language.html#where-clause

 ->andWhereIn("[fieldname]", [array[]]) 

数组数据示例(使用string和整数):

 $ids = array(1, 2, 3, 4); 

查询示例(适应您需要的地方):

 $q = dataTable::getInstance() ->createQuery() ->where("name = ?",'John') ->andWhereIn("image_id", $ids) ->orderBy('date_created ASC') ->limit(100); $q->execute();