如何在 DQL 中使用 RETURNING 更新查询

Posted

技术标签:

【中文标题】如何在 DQL 中使用 RETURNING 更新查询【英文标题】:How to use the RETURNING update query into the DQL 【发布时间】:2019-04-05 03:53:38 【问题描述】:

我正在尝试运行以下简单查询(它适用于 postgresql)

更新 ja_clients 设置 ref_inc_num = ref_inc_num + 1 其中 id = 43933 返回 ref_inc_num;

进入 DQL

$query = $this->entityManager->createQuery(); $query->setDQL("UPDATE Geoop\Core\Entity\Account a SET a.jobReferenceNumber__ = a.jobReferenceNumber__ + 1 WHERE a.id = :accountId RETURNING a.jobReferenceNumber__"); $query->setParameter('accountId', $account->getId()); $total = $query->getSingleScalarResult();

但重新调整此错误不起作用:

#30 /var/www/geoop_api/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php (line 861): Doctrine\ORM\Query\Parser->syntaxError(end of string)
#31 /var/www/geoop_api/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php (line 448): Doctrine\ORM\Query\QueryException::dqlError(UPDATE Geoop\Core\Entity\Account a SET a.jobReferenceNumber__ = a.jobReferenceNumber__ + 1  WHERE a.id = :accountId  RETURNING a.id as id)

【问题讨论】:

【参考方案1】:

DQL 不支持RETURNING 子句,所以需要use native SQL。您还必须create a result set mapping。

注意:我不知道您的表和列的实际名称,但假设它们与您的实体和属性命名相同,这将起作用:

$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addScalarResult('jobReferenceNumber', 'jobReferenceNumber');

$sql = "
    UPDATE account a
    SET a.jobReferenceNumber = a.jobReferenceNumber + 1
    WHERE a.id = :accountId
    RETURNING a.jobReferenceNumber
";

$query = $this->entityManager->createNativeQuery($sql, $rsm);
$query->setParameter('accountId', $account->getId());
$total = $query->getSingleScalarResult();

您可能需要更正我的示例中的表名和列名。使用本机 SQL 时,您必须使用数据库中的实际名称,而不是实体和属性的名称。另外,请记住 postgres 会将所有对象名称转换为大写,除非它们被引用。

【讨论】:

【参考方案2】:

感谢您的洞察力 :) 现在正在运行

这是我更新的代码: 在类上面我使用 ResultSetMapping

use Doctrine\ORM\Query\ResultSetMapping;

$rsm = new ResultSetMapping();
$rsm->addScalarResult('ref_inc_num', 'ref_inc_num');
$sql = "
UPDATE ja_clients
SET ref_inc_num = ref_inc_num + 1
WHERE id = :clientId
RETURNING ref_inc_num
";
$query = $this->entityManager->createNativeQuery($sql, $rsm);
$query->setParameter('clientId', $account->getId());
$refNum = $query->getSingleScalarResult();

【讨论】:

您的回答与 patrick3853 的the answer 有何不同,除了一些名字?

以上是关于如何在 DQL 中使用 RETURNING 更新查询的主要内容,如果未能解决你的问题,请参考以下文章

Java JDBC 如何使用 RETURNING 语句处理更新查询

使用 RETURNING INTO 子句和 BULK COLLECT 时如何返回整行

为啥我在更新语句后使用 RETURNING 子句时收到“NO DATA FOUND”异常?

MySQL的DQL语言(查)

尝试使用 RETURNING 和更新/插入从 plpgsql 函数返回时出错

如何在 PostgreSQL 中使用 RETURNING 和 ON CONFLICT?