Php 如何使用原则2中的WHERE

Php 如何使用原则2中的WHERE,php,doctrine-orm,query-builder,Php,Doctrine Orm,Query Builder,我有以下给出错误的代码: Message: Invalid parameter number: number of bound variables does not match number of tokens 代码: 数据(或$ID): DQL结果: q = SELECT COUNT(r.id) FROM \My\Entity\Rating r WHERE r.winner IN('?1') 我发现,不管文档中有什么指示,要让它发挥作用的唯一方法是: $ids = array(...);

我有以下给出错误的代码:

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

数据(或$ID):

DQL结果:

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

我发现,不管文档中有什么指示,要让它发挥作用的唯一方法是:

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

在研究这个问题的过程中,我发现了一些对任何遇到同样问题并寻求解决方案的人都很重要的东西

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

$qb->add('where', $qb->expr()->in('r.winner', array('?1')));
将命名参数包装为数组会导致绑定参数编号问题。通过将其从阵列包装中移除:

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

这个问题应该得到解决。这在早期版本的条令中可能是一个问题,但在最新版本的2.0中已修复。

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

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

最好的方法是(尤其是在添加多个条件的情况下):

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

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

并完成字符串解决方案

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

$qb->andWhere($qb->expr()->in('t.user_role_id', [
    User::USER_ROLE_ID_ADVERTISER,
    User::USER_ROLE_ID_MANAGER,
]));
我就是这样使用它的:

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

在2016年发现了如何做到这一点:

引述:

以下是如何正确地执行此操作:

$em->createQuery(“SELECT users 
     FROM Entities\User users 
     WHERE 
         users.id IN (:userids)”)
->setParameters(
     array(‘userids’ => $userIds)
);
方法
setParameters
将获取给定的数组并将其正确内爆,以便在“in”语句中使用

->where($qb->expr()->in('foo.bar', ':data'))
            ->setParameter('participants', $data);
还与以下方面合作:

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

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

您也可以通过以下方式从控制器执行
操作,其中在

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

我在同一个场景中挣扎,我不得不对一个值数组进行查询

以下几点对我很有用:

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

查询示例(根据需要进行调整):


我知道这是一个老帖子,但可能对某人有所帮助。我将通过回答ints评论中提出的问题来投票并增强@Daniel Espendiller的回答

为了使int的工作方式正确,请确保数组中的值的类型为int,您可以在传递前键入cast To 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中测试选择/删除这是几年后的事了,在一个旧站点上工作。。。就我的一生而言,我无法让
->and where()
->expr()->in()解决方案工作

最后查看了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。

不仅仅是从2开始。1@MaciejPyszyński+1。最简单的方法往往是最好的!快速提及:这在默认情况下适用于->setParameter('ids',$ids),但不适用于->setParameters('ids'=>$ids)。我花了几分钟的调试时间。使用->setParameters(…)
->where('b.status IN(:statuses))->setParameters(['customerId'=>$customerId',storeId'=>$storeId,'statuses'=>[status::OPEN,status::waiting_APPROVAL,status::APPROVED]])
我想指出将第三个参数传递给
setParameter
以强制
连接::PARAM_stru_数组
的重要性,我认为
$qb->expr()->in()
仅在条令2 ORM中,而不在条令DBAL中。
$qb->expr()->in())
确实在DBALI中,我认为这是推荐的方法,绝对是我的最佳解决方案:-)如果您有整数数组而不是字符串,也可以使用\doctor\DBAL\Connection::PARAM_INT_数组。这解决了我的问题(在
:userids周围的括号中),这是一种完全可以接受的方法,可以在不使用DQL的情况下执行where-in操作,但他的问题是关于他的DQL代码。他所做的不仅仅是简单的根据这些ID给我所有的东西。
->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();
 $qb->andWhere('foo.field IN (:ints)');
 $qb->setParameter('ints', array(1, 2), 
 \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
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());
}