简体   繁体   English

如何将 WHERE IN 与 Doctrine 2 一起使用

[英]How to use WHERE IN with Doctrine 2

I have the following code which gives me the error:我有以下代码,它给了我错误:

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

Code:代码:

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();
}

Data (or $ids):数据(或 $ids):

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

DQL result: DQL 结果:

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

The easiest way to do that is by binding the array itself as a parameter:最简单的方法是将数组本身绑定为参数:

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

In researching this issue, I found something that will be important to anyone running into this same issue and looking for a solution.在研究这个问题时,我发现了一些对遇到同样问题并寻找解决方案的人来说很重要的东西。

From the original post, the following line of code:从原始帖子中,以下代码行:

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

Wrapping the named parameter as an array causes the bound parameter number issue.将命名参数包装为数组会导致绑定参数编号问题。 By removing it from its array wrapping:通过从其数组包装中删除它:

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

This issue should be fixed.这个问题应该被修复。 This might have been a problem in previous versions of Doctrine, but it is fixed in the most recent versions of 2.0.这可能是 Doctrine 以前版本中的一个问题,但它在 2.0 的最新版本中得到了修复。

and for completion the string solution并完成字符串解决方案

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

I found that, despite what the docs indicate, the only way to get this to work is like this:我发现,尽管文档表明了什么,但让它工作的唯一方法是这样的:

$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 http://groups.google.com/group/doctrine-dev/browse_thread/thread/fbf70837293676fb

I know it's an old post but may be helpful for someone.我知道这是一个旧帖子,但可能对某人有帮助。 I would vote & enhance @Daniel Espendiller answer by addressing the question asked in comments about ints我会通过解决有关整数的评论中提出的问题来投票并增强@Daniel Espendiller 的回答

To make this work for int's in proper way, make sure the values in array are of type int, you can type cast to int before passing...为了以正确的方式为 int 工作,请确保数组中的值是 int 类型,您可以在传递之前将类型转换为 int...

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

Tested for select/delete in symfony 3.4 & doctrine-bundle: 1.8在 symfony 3.4 和学说包中测试选择/删除:1.8

I know the OP's example is using DQL and the query builder, but I stumbled upon this looking for how to do it from a controller or outside of the repository class, so maybe this will help others.我知道 OP 的示例使用 DQL 和查询构建器,但我偶然发现了这个,寻找如何从控制器或存储库类之外执行此操作,因此也许这对其他人有帮助。

You can also do a WHERE IN from the controller this way:您还可以通过以下方式从控制器执行WHERE IN

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

The best way doing this - especially if you're adding more than one condition - is:执行此操作的最佳方法 - 特别是如果您添加多个条件 - 是:

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

If your array of values contains strings, you can't use the setParameter method with an imploded string, because your quotes will be escaped!如果您的值数组包含字符串,则不能对内爆字符串使用 setParameter 方法,因为您的引号将被转义!

This is how I used it:这是我使用它的方式:

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

Found how to do it in the year of 2016: https://redbeardtechnologies.wordpress.com/2011/07/01/doctrine-2-dql-in-statement/在 2016 年找到了如何去做: https : //redbeardtechnologies.wordpress.com/2011/07/01/doctrine-2-dql-in-statement/

Quote:引用:

Here is how to do it properly:以下是如何正确执行此操作:

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

The method setParameters will take the given array and implode it properly to be used in the “IN” statement.方法setParameters将采用给定的数组并将其正确内爆以在“IN”语句中使用。

I prefer:我更喜欢:

$qb->andWhere($qb->expr()->in('t.user_role_id', [
    User::USER_ROLE_ID_ADVERTISER,
    User::USER_ROLE_ID_MANAGER,
]));
->where($qb->expr()->in('foo.bar', ':data'))
            ->setParameter('participants', $data);

Also works with:也适用于:

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

I struggled with this same scenario where I had to do a query against an array of values.我在同样的场景中挣扎,我不得不对一组值进行查询。

The following worked for me:以下对我有用:

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

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

Array data example (worked with strings and integers):数组数据示例(使用字符串和整数):

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

Query example (Adapt to where you need it):查询示例(适应你需要的地方):

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

$q->execute();

This is years later, working on a legacy site... For the life of me I couldn't get the ->andWhere() or ->expr()->in() solutions working.这是多年后,在一个遗留站点上工作......对于我的生活,我无法让->andWhere()->expr()->in()解决方案工作。

Finally looked in the Doctrine mongodb-odb repo and found some very revealing tests:最后查看了Doctrine mongodb-odb repo,发现了一些非常有启发性的测试:

public function testQueryWhereIn()
{ 
  $qb = $this->dm->createQueryBuilder('Documents\User');
  $choices = array('a', 'b');
  $qb->field('username')->in($choices);
  $expected = [
    'username' => ['$in' => $choices],
  ];
  $this->assertSame($expected, $qb->getQueryArray());
}

It worked for me!它对我有用!

You can find the tests on github here .您可以在此处找到 github 上的测试。 Useful for clarifying all sorts of nonsense.有助于澄清各种废话。

Note: My setup is using Doctrine MongoDb ODM v1.0.dev as far as i can make out.注意:据我所知,我的设置正在使用 Doctrine MongoDb ODM v1.0.dev。

$winnerIds = [1,3,5];
$qb->andWhere($qb->expr()->in('r.winner', ':winnerIds'))
   ->setParameter('winnerIds', $winnerIds)
;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM