在Doctrine ORM中是否可以将LIMIT添加到UPDATE查询中?

Rob*_*Rob 5 php doctrine symfony doctrine-orm

我正在使用Doctrine 2.5.x,并且在使LIMIT子句适用于UPDATE查询时遇到问题。它总是更新所有匹配的记录(即似乎忽略LIMIT子句)。

setMaxResults() 与UPDATE查询一起使用时似乎无效。

作为一种快速的解决方法,我正在使用本机MySQL查询,但这并不是最佳解决方案。

我尝试了以下示例,但没有一个起作用:

具有LIMIT的学说更新查询

https://recalll.co/app/?q=doctrine2%20-%20Doctrine%20update%20query%20with%20LIMIT

QueryBuilder与setMaxResults()(不起作用):

$qb = $em->createQueryBuilder();

$query = $qb->update('\Task\Entity', 't')
    ->set('t.ClaimedBy', 1)
    ->where('t.Claimed IS NULL')
    ->getQuery();
$query->setMaxResults(20);

$this->log($query->getSQL());
Run Code Online (Sandbox Code Playgroud)

希望有人可以找到比本地查询更好的解决方案。它剥夺了ORM的全部优势。

甚至可以在UPDATE语句中使用LIMIT子句吗?

β.ε*_*.βε 4

简而言之,不,因为 SQL 规范不支持UPDATE ... LIMIT ...,所以任何试图实现可移植性的 ORM 都不应该允许您这样做。


另请参阅MySQL 参考手册本身,其中指出这UPDATE ... LIMIT ...不是标准的 SQL 结构:

MySQL Server 支持一些您可能在其他 SQL DBMS 中找不到的扩展。请注意,如果您使用它们,您的代码将无法移植到其他 SQL 服务器。在某些情况下,您可以通过使用以下形式的注释来编写包含 MySQL 扩展但仍然可移植的代码:

  • SQL语句语法
    • UPDATE 和 DELETE 语句的 ORDER BY 和 LIMIT 子句。

因此,本质上,因为您想要实现的不是标准 SQL,ORM 将没有可移植的方式来实现它,并且可能根本不会实现它。


抱歉,您想要通过 DQL 实现的目标是不可能的,因为:

Ocramius在 2014 年 9 月 2 日发表评论
DQL 不允许对 UPDATE 查询进行限制,因为它不可移植。

正如本期DoctrineBundle 存储库所有者 Marco Pivetta(他也恰好是 ORM 存储库的所有者)所建议的那样。

更多信息,尽管可能需要正确的 ISO 规范文档的良好链接,但遗憾的是,该文档无法免费提供:

ISOUPDATE指令标准不允许使用,当然,其中 是允许的指令。LIMITUPDATESELECT

正如您自己提出的那样,ORM 的目的是不编写纯 SQL 以便使其跨 DBMS 兼容。如果不可能做到这一点,那么 ORM 不实现它也是有道理的。

另请注意,在 MYSQL 以外的其他 SQL 变体上,限制实际上是子句的一部分SELECT

select * from demo limit 10
Run Code Online (Sandbox Code Playgroud)

将在 SQL Server 中转换为

select top 10 from demo
Run Code Online (Sandbox Code Playgroud)

或者在 Orcale 中

select * from demo WHERE rownum = 1
Run Code Online (Sandbox Code Playgroud)

另请参阅:/sf/answers/74475621/