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

Joh*_*ohn 6 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();
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

 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();
    }
Run Code Online (Sandbox Code Playgroud)

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

小智 7

我相信实际的问题是由原则的 ->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();
}
Run Code Online (Sandbox Code Playgroud)

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


Vir*_*eja 1

教义表达式“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();
    }
Run Code Online (Sandbox Code Playgroud)