参数太少:查询定义了1个参数,但只能绑定0

时间:2017-06-07 12:31:05

标签: php symfony doctrine-orm

Symfony版本3.2.8

我不确定导致此错误的是什么,根据Doctrine Documentation正确使用了setParameter函数?

破码:

public function getNewShipChoices($uid, $fid) {
        /*Identify ships all ready added in fleet and do not allow them to be added again*/
        $q2 = $this->createQueryBuilder('c')
                    ->select('DISTINCT (c2.shipId)')
                    ->join('AppBundle:ShipsFleet', 'c2')
                    ->where('c.userid = :uid')->setParameter('uid', $uid)
                    ->andWhere('c2.fleetId = :fid')->setParameter('fid', $fid);

        $query = $this->createQueryBuilder('c3');
        $query->where($query->expr()->notIn('c3.shipId', $q2->getDQL()))->andWhere('c3.userid = :uid')->setParameter('uid', $uid);

        return $query->getQuery()->getResult();
    }

我尝试的另一件事是对setParameter值进行硬编码,这会带来相同的错误消息

 ->where('c.userid = :uid')->setParameter('uid', 1)
                            ->andWhere('c2.fleetId = :fid')->setParameter('fid', 1);

工作代码: 用硬编码值替换setParameter而不是传入2个整数值1和1都可以正常工作。

 public function getNewShipChoices($uid, $fid) {
        $q2 = $this->createQueryBuilder('c')
                    ->select('DISTINCT (c2.shipId)')
                    ->join('AppBundle:ShipsFleet', 'c2')
                    ->where('c.userid = 1')
                    ->andWhere('c2.fleetId = 1');

        $query = $this->createQueryBuilder('c3');
        $query->where($query->expr()->notIn('c3.shipId', $q2->getDQL()))->andWhere('c3.userid = 1');

        return $query->getQuery()->getResult();
    }

我是否错过了一些完全明显的东西?

4 个答案:

答案 0 :(得分:2)

我认为实际的问题是由教义的-> getDQL命令未传递参数值引起的。它会传递预期的参数,但只会在执行时将其水化。

在您的示例中,您已经在设置了fid参数之后将一些DQL传递给了select,但是没有在执行的查询中重新设置该参数,Doctrine不知道该参数,因此抛出预期的错误。

解决方法是:

public function getNewShipChoices($uid, $fid) {
    /*Identify ships all ready added in fleet and do not allow them to be added again*/
    $q2 = $this->createQueryBuilder('c')
                ->select('DISTINCT (c2.shipId)')
                ->join('AppBundle:ShipsFleet', 'c2')
                ->where('c.userid = :uid')
                ->andWhere('c2.fleetId = :fid');

    $query = $this->createQueryBuilder('c3');
    $query->where($query->expr()->notIn('c3.shipId', $q2->getDQL()))
        ->andWhere('c3.userid = :uid')
        ->setParameter('uid', $uid)
        ->setParameter('fid', $fid);;

    return $query->getQuery()->getResult();
}

请注意,$q2没有设置参数,因为传递DQL时会丢弃这些参数。

答案 1 :(得分:1)

为什么不尝试setParameters而不是setParameter?

$q2 = $this->createQueryBuilder('c')
->select('DISTINCT (c2.shipId)')
->join('AppBundle:ShipsFleet', 'c2')
->where('c.userid = :uid')
->andWhere('c2.fleetId = :fid')
->setParameters(['fid'=> $fid,'uid'=> $uid]);

答案 2 :(得分:0)

尝试将单引号添加到“1”。

->where('c.userid = :uid')->setParameter('uid', '1')
                        ->andWhere('c2.fleetId = :fid')->setParameter('fid', '1');

答案 3 :(得分:0)

学说表达' notIn'接受第二个参数中的数组值。你已经给出了查询。此外,您应该使用' setParameter'绑定参数。避免注射。 请试试这个。

public function getNewShipChoices($uid, $fid) {
        $shipIds = $this->createQueryBuilder('c')
                    ->select('DISTINCT (c2.shipId)')
                    ->join('AppBundle:ShipsFleet', 'c2')
                    ->where('c.userid = 1')
                    ->andWhere('c2.fleetId = 1')
                    ->getQuery()
                    ->getResult();

        $query = $this->createQueryBuilder('c3');
        $query->where($query->expr()->notIn('c3.shipId', $shipIds))->andWhere('c3.userid = :UserId')->setParameter(":UserId", $uid);

        return $query->getQuery()->getResult();
    }