

Doctrine2でのバルクUPDATE文についてです。  
DQLで以下のSQLを書き換えることは出来るでしょうか。

以下のようなMySQLでは動くSQLをそのまま流し込んでいる処理があります。

[code]

    $this->getConnection()->query(sprintf(
    'UPDATE %s p, (SELECT c.post_id, count(*) as total FROM %s as c WHERE c.status = 1 GROUP BY c.post_id) as count_comment
    SET p.comments_count = count_comment.total
    WHERE p.id = count_comment.post_id'
    , $postTableName, $commentTableName));
    
[/code]

PostgreSQLでも動かしたいので、DQLに書き直してみようかと思ったのですが、なかなかうまくいきません。

DQLのマニュアルにsub-selectsを使えばいけるとかかれているようにも見えるのですが。

> References to related entities are only possible in the WHERE clause and
> using > sub-selects.


CC BY-SA 3.0
2015-03-07T12:22:39.203
7586
2015-03-27T10:12:37.837
2015-03-26T16:07:47.097
8735
8735
question
php symfony2 doctrine2
Doctrineで副問い合わせを使用したバルクUPDATE文について


> References to related entities are only possible in the WHERE clause and
> using sub-selects.

EBNFを読むと、FROM句の部分はもちろんのこと、SET句で指定する値もサブクエリを許容しないSimpleArithmeticExpressionになっていますね。前述の英文は「
**WHERE句の中で** サブクエリを使う時だけ、関連エンティティを参照することができる」という意味合いなのでしょう。

だとすると下に書いた、サブクエリを使ったSQLもDQLで書き直すことはできないので・・・SQLを使ってはいかがですか？

[php - Doctrine Update query with a sub-query - Stack
Overflow](https://stackoverflow.com/questions/6779623/doctrine-update-query-
with-a-sub-query)

* * *

※以下 <https://ja.stackoverflow.com/revisions/7586/9> の時に書いた回答です

sub-selectというのは恐らくこういうのですね。個人的にはこっちが「副問い合わせ」のような気がしますが。。

[code]

    UPDATE hoge
    SET foo = (SELECT count(*) FROM piyo)
    
[/code]

とか

[code]

    UPDATE hoge
    SET foo = 1
    WHERE bar IN (SELECT id FROM piyo)
    
[/code]

MySQLのマニュアルでは Subquery と書かれています。

[MySQL :: MySQL 5.7 Reference Manual :: 13.2.10 Subquery
Syntax](https://dev.mysql.com/doc/refman/5.7/en/subqueries.html)

`UPDATE table1, table2 SET ...` という書き方はMySQLの独自拡張なので DQL
では使えないというのが、質問に引用されている JIRA や StackOverflow に書かれたコメントです。

QueryBuilder
はわかりませんが、副問い合わせを使ったSQLに書き直すならこんな感じでどうでしょうか。このSQLは恐らくMySQLでもPostgreSQLでも動作します。

[code]

    UPDATE %s p 
    SET
      p.comments_count = (
        SELECT count(*) FROM %s c WHERE c.status = 1 AND c.post_id = p.id
      )
    
[/code]


CC BY-SA 3.0
2015-03-26T07:09:00.170
8423
2015-03-27T10:12:37.837
2017-05-23T12:38:55.307
-1
8000
7586
answer