Doctrine Query Builder不使用UPDATE和INNER JOIN

时间:2013-03-08 11:58:53

标签: database symfony doctrine-orm dql

在我的存储库中,我有这个查询:

$qb = $this->getEntityManager()->createQueryBuilder();
$qb
    ->update('MyBundle:Entity1', 'e1') 
    ->join('e1.Entity2', 'e2')
    ->set('e1.visibile', '1')
    ->andWhere('e2.id = :id')->setParameter("id", 123)
;

抛出此错误

[Semantical Error] line 0, col 66 near 'e2.id = :id': Error: 'e2' is not defined

我检查了这种关系,这是正确的。 在查询更新中使用join是否有任何问题?

4 个答案:

答案 0 :(得分:12)

您无法在更新和删除查询时使用联接。你必须使用子查询。

  

更新和删除查询不支持联接,因为它不是   所有dbms都支持。它不会在Doctrine 1或者Doc中实现   原则2.然而,您可以通过使用子查询获得相同的效果。

http://www.doctrine-project.org/jira/browse/DC-646

如果您使用的是MySQL,则使用子查询将无效。然后,您将使用2个查询。

  

在MySQL中,您无法修改表并从中选择同一个表   子查询

http://dev.mysql.com/doc/refman/5.0/en/subqueries.html

答案 1 :(得分:6)

Doctrine DQL不支持join in update。

尝试执行以下操作:

$qb = $this->getEntityManager()->createQueryBuilder();
$qb
    ->update('MyBundle:Entity1', 'e1') 
    ->set('e1.visibile', '1')
    ->where('e1.Entity2 = :id')
    ->setParameter("id", 123)
;

您可以直接设置链接实体的ID(只要它是主键),就像它是实体一样,Doctrine会映射它。

我在查询中做了完全相同的事情并且它有效。

答案 2 :(得分:3)

尝试使用子查询代替Join will not work in DQL while you re doing an update

  

LEFT JOIN或特别是JOIN仅在UPDATE中受支持   MySQL的陈述。 DQL抽象了一个常见的ansi sql的子集,所以   这是不可能的。尝试使用子选择:

$qb = $this->getEntityManager()->createQueryBuilder();
    $qb ->update('MyBundle:Entity1', 'e') 
        ->set('e.visibile', '1')
        ->where('e.id IN (SELECT e1.id FROM Entity1 e1 INNER JOIN e2.Entity2 e2 WHERE e2 = :id')
        ->setParameter("id", 123);

答案 3 :(得分:1)

非常老的问题,但在完整的查询构建器中不包含答案。

是的,以下查询无法同步两个表的字段:

select decode(col1,'1','yes','no') from mytable

生成的查询不包含该关系,因为如上所述,该查询在所有dbms中均缺乏支持。他们还告诉您改为使用子查询。

这就是我所做的等效操作(即使使用2个查询并且性能较低...):

$this->createQueryBuilder('v')
    ->update()
    ->join(Pegass::class, 'p', Join::WITH, 'v.identifier = p.identifier')
    ->set('v.enabled', 'p.enabled')
    ->where('p.type = :type')
    ->setParameter('type', Pegass::TYPE_VOLUNTEER)
    ->andWhere('v.enabled <> p.enabled');