And*_*ord 2 sql doctrine symfony
我正在开发一个基于 Symfony 2.8 的项目来管理联系人。用户可以从列表中选择任意数量的联系人,并且应该能够一次删除所有选定的联系人。如何在单个 Query Builder 语句中完成此操作?
// Contact entity uses a GUID as ID
$guids = array(...);
try {
$this->getEntityManager()->getConnection()->beginTransaction();
$qb = $this->getEntityManager()->getConnection()->createQueryBuilder()
->delete('AppBundle:Contact', 'c')
->where('c.guid in (:guids)')
->setParameter(':guids', array($guids, Connection::PARAM_STR_ARRAY));
log($qb->getSql());
$qb->execute();
$this->getEntityManager()->flush();
$this->getEntityManager()->getConnection()->commit();
} catch (\Exception $ex) {
// Rollback the transaction
$this->getEntityManager()->getConnection()->rollback();
}
Run Code Online (Sandbox Code Playgroud)
1. 问题
寻址实体AppBundle:Contact(在构建SELECT语句时没有任何问题)不起作用。这是日志输出:
Query: DELETE FROM AppBundle:Contact c WHERE c.guid in (:guids)
Exception: Doctrine\DBAL\SQLParserUtilsException: Value for :Contact not found in params array. Params array key should be "Contact" in
Run Code Online (Sandbox Code Playgroud)
2. 问题
使用表名 ( ->delete('contact', 'c')) 也不起作用:
Query: DELETE FROM contact c WHERE c.guid in (:guids)
Exception: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'c WHERE c.guid in ('Array')'
Run Code Online (Sandbox Code Playgroud)
3. 问题
删除单个实体也不起作用:
->delete('contact', 'c')
->where('c.guid = (:guid)')
->setParameter(':guid', $guids[0]);
Query: DELETE FROM contact c WHERE c.guid = :guid
Exception: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'c WHERE c.guid = 'E7516B91-0549-4FFB-85F2-4BD03DC3FFC1''
Run Code Online (Sandbox Code Playgroud)
她可能有什么问题?
第一。问题。将 setParameter 行更改为以下内容,您不需要在参数名称中使用 : 。
->setParameter('guids', $guids);
Run Code Online (Sandbox Code Playgroud)
第二个问题- 如果您正在处理 queryBuilder,则不应使用真实的表名。
第三个问题- 你的逻辑不正确。如果你想删除单个然后
$qb = $this->getEntityManager()->createQueryBuilder()
->delete('AppBundle:Contact', 'c')
->where('c.guid = :guid')
->setParameter('guid', $guids[0]);
Run Code Online (Sandbox Code Playgroud)
此外
我真的不知道你使用的是什么教义版本,但是
$this->getEntityManager()->getConnection()->createQueryBuilder() - 似乎是错误的,因为如果您想执行 RAW SQL,通常会获得连接。
尝试更改为
$qb = $this->getEntityManager()->createQueryBuilder()
Run Code Online (Sandbox Code Playgroud)
并且仅当它是数组时才需要在变量周围使用方括号。检查下面的代码
$queryBuilder->andWhere('r.id IN (:ids)')
->setParameter('ids', $ids);
Run Code Online (Sandbox Code Playgroud)
小智 7
除非您想执行原始 SQL,否则不必使用实体管理器的连接,因此您可以替换$this->getEntityManager()->getConnection()->createQueryBuilder()为
$em->createQueryBuilder()
你可以做类似的事情
$qb = $this->createQueryBuilder()
->delete('AppBundle:Contact', 'c')
->where('c.guid in (:guids)')
->setParameter(':guids', $guids);
Run Code Online (Sandbox Code Playgroud)
如果你想记录/执行它
$query = $qb->getQuery();
log($query->getSql());
$query->execute();
Run Code Online (Sandbox Code Playgroud)
也不需要添加beginTransaction和rollback,如果查询失败并抛出异常,学说会自动回滚。