sql - 如何使用queryBuilder修复“错误:预期文字,得到'SELECT'”?
问题描述
我的查询有问题,当我尝试进行子查询时,出现此错误消息
"hydra:description": "[Syntax Error] line 0, col 85: Error: Expected Literal, got 'SELECT'",
对于我的 EventRepositoty CLass 中的这个查询:
public function updateMoveAtField(string $eventLabel, $cameraId)
{
$queryBuilder = $this->createQueryBuilder('e');
$subQueryBuilder = $this->createQueryBuilder('ev');
$subQuery = $subQueryBuilder
->select('MAX(ev.arrivedAt) as arrived')
->andWhere('ev.camera = ?1')
->setParameter(1, $cameraId)
->getQuery()->getDQL()
;
$event = $queryBuilder
->update()
->set('e.moveAt', '?1')
->where('e.label = ?2')
->andWhere('e.camera = ?3')
->andWhere($queryBuilder->expr()->andX($subQuery))
->setParameter(1, new \DateTime())
->setParameter(2, $eventLabel)
->setParameter(3, $cameraId);
return $event->getQuery()->execute();
}
我该如何解决?
我不知道你是否能理解我的要求,所以让我解释一下:当标签和相机与查询中发送的相同时,我想更新字段“moveAt”。所以我做了一个子查询,因为我想要其他条件(总是更新最后一个)。我做了一个子查询,因为我无法在更新查询中添加选择。
编辑:来自@Preciel 帮助的 DQL 转储结果
“从 App\Entity\Event e 中选择 MAX(e.arrivedAt) 其中 e.label=:var2 AND e.camera=:var3 AND e.camera=:var3 AND (e.arrivedAt <= SELECT MAX(e.arrivedAt) FROM App\Entity\Event e WHERE e.label=:var2 AND e.camera=:var3 AND e.camera=:var3)"
新 =
“更新 App\Entity\Event e SET event.moveAt = :var1 WHERE e.label=:var2 AND e.camera=:var3 AND e.arrivedAt <= SELECT MAX(ev.arrivedAt) FROM App\Entity\Event ev WHERE ev.camera=:var3"
子查询
“从 App\Entity\Event ev WHERE ev.camera=:var3 中选择 MAX(ev.arrivedAt)”
解决方案
我会尝试做这样的事情:
public function updateMoveAtField($eventLabel, $cameraId) {
$qb=$this->createQueryBuilder("event");
$sqb=$this->createQueryBuilder("eventBis");
$qb->update()
->set("event.moveAt", ":var1")
->andWhere("event.lavel=:var2")
->andWhere("event.camera=:var3")
->andWhere(
$qb->expr()->lte("event.arrivedAt",
"(".$sqb->select($qb->expr()->max("eventBis.arrivedAt")) //Your sub query start here
->andWhere("eventBis.camera=:var3")->getDQL().")")) //and end here
->setParameters(array(
'var1'=>new \DateTime(),
'var2'=>$eventLabel,
'var3'=>$cameraId,
));
// dump($qb->getDQL());
// dump($qb->getQuery()->getSQL());
// exit();
return $qb->getQuery()->execute();
}
我添加了 2 行转储。如果它不起作用,请先转储 DQL,然后转储 SQL(SQL 可能会失败),请在评论中添加它们。
在第一次使用时expr()
,我使用了lte()
(小于或等于)。根据您的需要更改它(gt()、gte()、eq()、lte()、lt())。
提示 :
- 始终使用双引号进行查询。Doctrine 将只接受字符串值的单引号(单引号可用于参数)。
- 永远不要使用
where()
,总是以andWhere()
或开头orWhere()
- 避免使用
andWhere()
和orWhere()
在一起。更喜欢expr()
(在这里阅读更多) - 避免将 DQL 与伪原生(
LIKE
、IN
等)SQL 混合使用。如果 Doctrine 读取了一些它不能使用的原生 SQL,它会咀嚼你。改为使用expr()
。如果您在 中找不到您需要的内容expr()
,则意味着您应该创建一个原生查询。 - 完整命名您的别名,以便以后阅读。
[编辑]
这是我的回答中给出的转储查询的屏幕截图。我认为您试图使我的查询适应您的代码,而不仅仅是复制/粘贴它。别名与我在查询中写的不匹配。
除了别名之外,我们可以看到子查询周围缺少一对括号。刚刚在我的答案中添加了它们。如果您复制/粘贴我的代码,它应该可以解决您的问题。
推荐阅读
- docker - 配置以通过 gitlab-ci 将 minio docker 容器作为服务运行以进行测试
- jquery - 如何在不关闭引导模式的情况下提交注册表单并返回结果
- javascript - 回显 PHP 默认选中的 JSTree 列表项
- php - 我想在 wp 媒体文件夹中上传 PDF 文件并更新 ACF 字段
- angular - 模板解析错误:没有将“exportAs”设置为“matMenu”的指令
- c - I could not find the problem with my code
- asp.net-mvc - View is expecting for viewmodel while List item has been passed to controller
- html - Why is the ul with class "subnav" not bigger?
- r - 使用 ARMA(1,1) 预测误差与 GARCH(1,1) 进行预测
- python - Uploading to Bigquery with correctly provided timezone in timestamp (prevent auto UTC)