我正在尝试使用doctrine dql执行一个类似于下面的查询:
Doctrine_Query::create()
->update('Table a')
->set('a.amount',
'(SELECT sum(b.amount) FROM Table b WHERE b.client_id = a.id AND b.regular = ? AND b.finished = ?)',
array(false, false))
->execute();
但它上升了一个Doctrine_Query_Exception,并显示消息:“Unknown component alias b”
关于在'set'子句中使用子查询的限制,你能给我一些帮助吗?
提前致谢。
答案 0 :(得分:3)
多年以后但可能有所帮助。
如果您需要/想要/必须,您可以使用 Querybuilder 执行具有子选择语句的更新查询,而不是直接使用基础连接层。
这里的想法是使用QueryBuilder两次。
给定用户可以销售对象的应用程序。每笔交易涉及买方和卖方。交易结束后,卖家和买家可以对如何与他们的对手部分进行交易进行审查
您可能需要用户表,审核表和交易表。
User表包含名为 rating 的字段,该字段将保留用户的平均评级。 Review表存储事务ID,作者ID(提交评论的人),值(从0到5)。最后,交易包含卖方和买方的参考。
现在让我们说在计数器部分提交审核后,您希望更新用户的平均评分。更新查询将计算用户的平均评级,并将结果作为User.rating
属性的值
我在 Doctrine 2.5 和 Symfony3 中使用了以下代码段。由于工作涉及用户,因此我有必要在 AppBundle \ Entity \ UserRepository.php 存储库中创建一个名为updateRating( User $user)
的新公共函数。
/**
* Update the average rating for a user
* @param User $user The user entity object target
*/
public function updateRating( User $user )
{
// Compute Subrequest. The reference table being Transaction, we get its repository first.
$transactionRepo = $this->_em->getRepository('AppBundle:Transaction');
$tqb = $postRepo->createQueryBuilder('t');
#1 Computing select
$select = $tqb->select('SUM(r.value)/count(r.value)')
// My Review table as no association declared inside annotation (because I do not need it elsewhere)
// So I need to specify the glue part in order join the two tables
->leftJoin('AppBundle:Review','r', Expr\Join::WITH, 'r.post = p.id AND r.author <> :author')
// In case you have an association declared inside the Transaction entity schema, simply replace the above leftJoin with something like
// ->leftJoin(t.reviews, 'r')
// Specify index first (Transaction has been declared as terminated)
->where( $tqb->expr()->eq('t.ended', ':ended') )
// The user can be seller or buyer
->andWhere( $tqb->expr()->orX(
$tqb->expr()->eq('t.seller', ':author'),
$tqb->expr()->eq('t.buyer', ':author')
));
#2 The actual update query, containing the above sub-request
$update = $this->createQueryBuilder('u')
// We want to update a row
->update()
// Setting the new value using the above sub-request
->set('u.rating', '('. $select->getQuery()->getDQL() .')')
// should apply to the user we want
->where('u.id = :author')
// Set parameters for both the main & sub queries
->setParameters([ 'ended' => 1, 'author' => $user->getId() ]);
// Get the update success status
return $update->getQuery()->getSingleScalarResult();
}
现在来自控制器
// … Update User's rating
$em->getRepository('AppBundle:User')->updateRating($member);
// …
答案 1 :(得分:1)
我不确定这是否有限制,但我记得前一段时间与此斗争。我最终得到了它:
$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$q->execute("UPDATE table a SET a.amount = (SELECT SUM(b.amount) FROM table b WHERE b.client_id = a.id AND b.regular = 0 AND b.finished = 0)");
看看是否有诀窍。请注意,此查询不会执行自动变量转义,因为它不是DQL。