【问题标题】:Can't use same parameter twice in custom function不能在自定义函数中使用相同的参数两次
【发布时间】:2011-12-16 08:41:40
【问题描述】:

我编写了一个自定义 DQL 函数。在这个函数中,我两次使用相同的参数:

public function getSql(SqlWalker $sqlWalker)
{
    $point1_lat = $this->point1_lat->dispatch($sqlWalker);
    $point1_lon = $this->point1_lon->dispatch($sqlWalker);
    $point2_lat = $this->point2_lat->dispatch($sqlWalker);
    $point2_lon = $this->point2_lon->dispatch($sqlWalker);

    $unitFactor = 6366.56486; // earth radius in km

    return "
        $unitFactor *
        2 * 
        ASIN(
            SQRT(
                POWER(
                    SIN(($point1_lat - $point2_lat) * pi()/180/2),
                    2
                ) + 
                COS($point1_lat * pi()/180) * 
                COS($point2_lat * pi()/180) * 
                POWER(
                    SIN(($point1_lon - $point2_lon) * pi()/180/2), 
                    2
                )
            )
        )
    ";
}

这是查询的执行方式:

    $q = \App::get()->getEntityManager()->createQuery('
        SELECT
            s,
            GEO_DISTANCE(
                :lat, 
                :lng,
                s.glat,
                s.glng
            ) AS distance
        FROM
            \Application\Geo\Entity\Street s
    ');
    $q->setMaxResults(10);
    $q->setParameters(array(
        'lat' => 52.25948,
        'lng' => 6.76403,
    ));
    $result = $q->getResult();

然而,这给了我以下例外:

消息:SQLSTATE[HY093]: Invalid parameter number: number of bound 变量与令牌数不匹配

getSql()返回如下SQL:

        6366.56486 *
        2 * 
        ASIN(
            SQRT(
                POWER(
                    SIN((? - g0_.glat) * pi()/180/2),
                    2
                ) + 
                COS(? * pi()/180) * 
                COS(g0_.glat * pi()/180) * 
                POWER(
                    SIN((? - g0_.glng) * pi()/180/2), 
                    2
                )
            )
        )

所以我猜想抛出异常是因为命名参数作为索引参数返回。这是教义中的错误还是我做错了什么?

【问题讨论】:

    标签: doctrine-orm dql


    【解决方案1】:

    这不是错误,每个参数只能使用一次,因为dispatch() 函数将值放入堆栈一次,以匹配一个 @987654322查询中的@占位符。

    作为一种解决方法,您可以多次调用 dispatch():

    public function getSql(SqlWalker $sqlWalker)
    {
        $point1_lat_a = $this->point1_lat->dispatch($sqlWalker);
        $point1_lat_b = $this->point1_lat->dispatch($sqlWalker);
        $point1_lon = $this->point1_lon->dispatch($sqlWalker);
    
        $point2_lat_a = $this->point2_lat->dispatch($sqlWalker);
        $point2_lat_b = $this->point2_lat->dispatch($sqlWalker);
        $point2_lon = $this->point2_lon->dispatch($sqlWalker);
    
        $unitFactor = 6366.56486; // earth radius in km
    
        return "
            $unitFactor *
            2 * 
            ASIN(
                SQRT(
                    POWER(
                        SIN(($point1_lat_a - $point2_lat_a) * pi()/180/2),
                        2
                    ) + 
                    COS($point1_lat_b * pi()/180) * 
                    COS($point2_lat_b * pi()/180) * 
                    POWER(
                        SIN(($point1_lon - $point2_lon) * pi()/180/2), 
                        2
                    )
                )
            )
        ";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      • 2016-06-30
      • 1970-01-01
      • 2021-06-26
      相关资源
      最近更新 更多