我正在尝试使用Doctrine QueryBuilder来执行以下SQL查询:
DELETE php FROM product_hole_pattern php
INNER JOIN hole_pattern hp ON php.hole_pattern_id = hp.id
INNER JOIN hole_pattern_type hpt ON hp.hole_pattern_type_id = hpt.id
WHERE php.product_id = 4 AND hpt.slug='universal';
我有这个
$qb = $this->entityManager->createQueryBuilder();
$query = $qb->delete('\SANUS\Entity\ProductHolePattern', 'php')
->innerJoin('php.holePattern', 'hp')
->innerJoin('hp.holePatternType', 'hpt')
->where('hpt.slug = :slug AND php.product=:product')
->setParameter('slug','universal')
->setParameter('product',$this->id)
->getQuery();
但我明白了:
[Semantical Error] line 0, col 50 near 'hpt.slug = :slug': Error: 'hpt' is not defined.
错误消息附带的DQL是:
DELETE \SANUS\Entity\ProductHolePattern php
WHERE hpt.slug = :slug AND php.product=:product
所以连接似乎完全被省略了。
答案 0 :(得分:10)
看起来DQL不支持这种删除语句。 BNF from the Doctrine documentation表示delete_statement
必须采用
delete_clause [where_clause]
delete_clause
定义为:
"DELETE" "FROM" abstract_schema_name [["AS"] identification_variable]
所以我可以提供一个schema和一个where子句,但是没有连接。
答案 1 :(得分:10)
实现此目的的方法可能是首先使用连接查询要删除的实体:
$qb = $this->entityManager->createQueryBuilder();
$query = $qb->select('\SANUS\Entity\ProductHolePattern', 'php')
->innerJoin('php.holePattern', 'hp')
->innerJoin('hp.holePatternType', 'hpt')
->where('hpt.slug = :slug AND php.product=:product')
->setParameter('slug','universal')
->setParameter('product',$this->id)
->getQuery();
$results = $query->execute();
然后删除在结果中找到的实体:
foreach ($results as $result) {
$this->entityManager->remove($result);
}
请务必致电
$this->entityManager->flush();
在您的应用程序中的适当位置(通常是控制器)。
答案 2 :(得分:5)
运行具有IN条件的查询可能比迭代更好。
[standalone@localhost:9990 /] deploy /Users/ebeid/code/dcm4chee-arc-light/dcm4chee-arc-ear/target/dcm4chee-arc-ear-5.14.0-psql.ear
{"WFLYCTL0062: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"WFLYCTL0080: Failed services" => {"jboss.deployment.subunit.\"dcm4chee-arc-ear-5.14.0-psql.ear\".\"dcm4chee-arc-service-5.14.0.jar\".component.ArchiveServiceImpl.START" => "java.lang.IllegalStateException: WFLYEE0042: Failed to construct component instance
Caused by: java.lang.IllegalStateException: WFLYEE0042: Failed to construct component instance
Caused by: javax.ejb.EJBException: org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void org.dcm4chee.arc.impl.ArchiveDeviceProducer.init() on org.dcm4chee.arc.impl.ArchiveDeviceProducer@2c9c434
Caused by: org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void org.dcm4chee.arc.impl.ArchiveDeviceProducer.init() on org.dcm4chee.arc.impl.ArchiveDeviceProducer@2c9c434
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.dcm4che3.opencv.NativeJLSImageWriter"}}}}
对于激烈的“放置在哪里”的辩论,如果愿意,可以将其放在控制器中。这完全取决于您。但是,如果您将代码放入专用的学说存储库类中,那么将来对您可能会更有用。它应该非常容易做,并且易于更改/维护。
答案 3 :(得分:-3)
在Symfony2上,请尝试:
foreach ($results as $result) {
$em->remove($result);
}
$em->flush();
多数人。