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

发布于 2024-11-05 18:43:39 字数 1053 浏览 6 评论 0原文

我有以下代码,但出现错误:

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')

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):

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

DQL result:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

反差帅 2024-11-12 18:43:39

最简单的方法是将数组本身绑定为参数:

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

The easiest way to do that is by binding the array itself as a parameter:

$queryBuilder->andWhere('r.winner IN (:ids)')
             ->setParameter('ids', $ids);
信仰 2024-11-12 18:43:39

在研究这个问题时,我发现了一些对于遇到同一问题并寻求解决方案的人来说很重要的东西。

在原始帖子中,以下代码行:

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

将命名参数包装为数组会导致绑定参数编号问题。通过将其从数组包装中删除:

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

此问题应该得到解决。这可能是以前版本的 Doctrine 中的一个问题,但在最新版本的 2.0 中已修复。

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.

七秒鱼° 2024-11-12 18:43:39

并完成字符串解决方案

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

and for completion the string solution

$qb->andWhere('foo.field IN (:string)');
$qb->setParameter('string', array('foo', 'bar'), \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
携余温的黄昏 2024-11-12 18:43:39

我发现,尽管文档表明了这一点,但让它工作的唯一方法是这样的:

$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

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

北方。的韩爷 2024-11-12 18:43:39

我知道这是一篇旧帖子,但可能对某人有帮助。我会投票&通过解决有关 int 的评论中提出的问题来增强@Daniel Espendiller 的答案

为了以正确的方式使 int 工作,请确保数组中的值是 int 类型,您可以在传递之前键入强制转换为 int ...

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

测试了 select/在 symfony 3.4 & 中删除学说包:1.8

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

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...

 $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

爱殇璃 2024-11-12 18:43:39

我知道 OP 的示例是使用 DQL 和查询生成器,但我在寻找如何从控制器或存储库类外部执行此操作时偶然发现了这一点,所以也许这会对其他人有所帮助。

您还可以通过以下方式从控制器执行 WHERE IN

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

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.

You can also do a WHERE IN from the controller this way:

// Symfony example
$ids    = [1, 2, 3, 4];
$repo   = $this->getDoctrine()->getRepository('AppBundle:RepoName');
$result = $repo->findBy([
    'id' => $ids
]);
箹锭⒈辈孓 2024-11-12 18:43:39

这就是我的使用方式:

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

This is how I used it:

->where('b.status IN (:statuses)')
->setParameters([
                'customerId' => $customerId,
                'storeId'    => $storeId,
                'statuses'   => [Status::OPEN, Status::AWAITING_APPROVAL, Status::APPROVED]
            ]);
铜锣湾横着走 2024-11-12 18:43:39

执行此操作的最佳方法 - 特别是如果您添加多个条件 - 是:

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

如果您的值数组包含字符串,则不能将 setParameter 方法与内爆字符串一起使用,因为您的引号将被转义!

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!

电影里的梦 2024-11-12 18:43:39

在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”语句中。

Found how to do it in the year of 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.

窗影残 2024-11-12 18:43:39
$qb->where($qb->expr()->in('r.winner', ':ids'))
    ->setParameter('ids', $ids);

还适用于:

$qb->andWhere($qb->expr()->in('r.winner', ':ids'))
    ->setParameter('ids', $ids);
$qb->where($qb->expr()->in('r.winner', ':ids'))
    ->setParameter('ids', $ids);

Also works with:

$qb->andWhere($qb->expr()->in('r.winner', ':ids'))
    ->setParameter('ids', $ids);
破晓 2024-11-12 18:43:39

我更喜欢:

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

I prefer:

$qb->andWhere($qb->expr()->in('t.user_role_id', [
    User::USER_ROLE_ID_ADVERTISER,
    User::USER_ROLE_ID_MANAGER,
]));
桃酥萝莉 2024-11-12 18:43:39

我在同样的场景中遇到了困难,我必须对一组值进行查询。

以下内容对我有用:

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

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

数组数据示例(使用字符串和整数):

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

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

->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();
红ご颜醉 2024-11-12 18:43:39

这是几年后的事了,在一个遗留网站上工作......我一生都无法得到 ->andWhere()->expr()->; in() 解决方案有效。

最后查看了 Doctrine mongodb-odb 存储库,发现了一些非常有启发性的测试:

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

它对我有用!

您可以在 github 上找到测试 此处。对于澄清各种废话很有用。

注意:据我所知,我的设置使用的是 Doctrine MongoDb ODM v1.0.dev。

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.

Finally looked in the Doctrine mongodb-odb repo and found some very revealing tests:

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. 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.

泛滥成性 2024-11-12 18:43:39
$winnerIds = [1,3,5];
$qb->andWhere($qb->expr()->in('r.winner', ':winnerIds'))
   ->setParameter('winnerIds', $winnerIds)
;
$winnerIds = [1,3,5];
$qb->andWhere($qb->expr()->in('r.winner', ':winnerIds'))
   ->setParameter('winnerIds', $winnerIds)
;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文