【问题标题】:DQL Query Using Variable in Select Statement Returning Exception在 Select 语句中使用变量的 DQL 查询返回异常
【发布时间】:2017-05-28 23:23:19
【问题描述】:

我得到这个异常:

[Semantical Error] line 0, col 124 near 'column = :column': Error: 'column' is not defined.

尝试运行此代码时:

/**
 * @param User $user
 * @param String $column
 * @return array
 */
public function getStatsByDQL(User $user, String $column)
{
    $midNight = date_create('00:00:00')->format('Y-m-d H:i:s');

    $em2 = $this->getDoctrine()->getManager()->getRepository('AppBundle:ExerciseStats')
        ->createQueryBuilder('g')
        ->setParameters(array(
            'user' => $user, 'column' => $column, 'date' => $midNight,
        ))
        ->where('user = :user', 'g.timestamp < :date',  'column = 
:column')
        ->select('g.column')
        ->setMaxResults(1)
        ->join('g.user', 'user')
        ->orderBy('g.column','DESC')

        ->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
        return $em2;

这是它的执行方式:

$yy = $this->getStatsByDQL($usr, 'bench_press_1_weight');
    var_dump($yy);

当 'g.column' 替换为 'bench_press_1_weight' 时,此 DQL 查询运行良好,但将 g.column 放置在那里时会出错。我认为 'bench_press_1_weight' 应该被传递,因为我在参数'column' => $column 中设置了。对我来说,这应该有效。我还没有发现 Doctrine 文档有任何用处,并且尝试了无数种组合。

此功能在我的默认控制器中。

谁有线索?提前致谢!

【问题讨论】:

  • 那么你实际上有一个名为column的数据库表列?列是mysql中的保留字,所以不会很好结束。
  • 其实我没有column这个列,看代码就知道是变量名。这是 DQL,而不是 SQL,所以我在那里很安全。为了安全起见,我用另一个变量名对其进行了测试,结果没有任何区别,同样的错误消息。
  • DQL 转换为 SQL,因此适用相同的限制。 'column = :column' 强烈暗示名为 column 的列,错误消息也是如此。您是否尝试动态指定实际列?我想我只是不了解设计。 dump($qb->getQuery()->getSQL() 会显示生成的sql。
  • 我有 50 列可以从中获取数据,因此使用了变量。我已将变量从列更改为安全起见,仅供参考(出现相同的错误消息)。所以,我想使用 consts 来调用(其中 'bench_press_1_weight' 将是一个常量。顺便说一下,bench_press_1_weight 是数据库中的列之一(大约有 50 个类似的列,每个都需要单独调用在不同的时间)。希望能澄清事情。谢谢。
  • 因此将 ->select('g.column') 更改为 ->select('g.' . $column) 并对 orderby 执行相同操作。并从 where 语句中完全删除列内容。

标签: symfony doctrine dql


【解决方案1】:

尝试改变这一点

    ->setParameters(array(
        'user' => $user, 'column' => $column, 'date' => $midNight,
    ))
    ->where('user = :user', 'g.timestamp < :date',  'column = :column')

    ->where('user = :user', 'g.timestamp < :date',  'column = :column')
    ->setParameters(array(
        'user' => $user, 'column' => $column, 'date' => $midNight,
    ))

【讨论】:

  • 我已经做到了,它并没有改变任何东西。感谢您的意见。
【解决方案2】:

尝试改变这一点

->setParameters(array(
    'user' => $user, 'column' => $column, 'date' => $midNight,
))
->where('user = :user', 'g.timestamp < :date',  'column = :column')

有了这个

尝试改变这一点

->setParameters(array(
    'user' => $user, 'column' => $column, 'date' => $midNight,
))
->where('g.user = :user', 'g.timestamp < :date',  'g.column = :column')

【讨论】:

  • 当我按照您的建议执行时,我得到了这个:[Semantical Error] line 0, col 142 near 'column = :column ORDER': Error: Class AppBundle\Entity\ExerciseStats has no field or association named列
【解决方案3】:

我已经解决了这个问题,太简单了,我差点开枪了。所以需要做的是从 params 和 WHERE 语句中删除函数签名中引入的变量,它看起来像这样:

public function getStatsByDQL(User $user,  String $col)
{

    $midNight = date_create('00:00:00')->format('Y-m-d H:i:s');
    $parameters = (array('user' => $user, 'date' => $midNight, 

    ));
    $em2 = $this->getDoctrine()->getManager()->getRepository('AppBundle:ExerciseStats')
        ->createQueryBuilder('g')
        ->setParameters($parameters)
        ->where('g.user = :user', 'g.timestamp < :date')
        ->select('g.'. $col)
        ->setMaxResults(1)
        ->join('g.user', 'user')
        ->orderBy( 'g.'. $col,'DESC')
        ->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
    return $em2;
}

这将返回我所追求的正确数据,即请求的列及其内容。感谢大家的意见。非常感激。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    相关资源
    最近更新 更多