Как удалить несколько объектов, используя Doctrine QueryBuilder - PullRequest
0 голосов
/ 26 апреля 2018

Я работаю над проектом 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();
} 

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

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')'

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''

Что может быть не так с ней?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Если вы не хотите выполнять сырой SQL, вам не нужно использовать соединение вашего менеджера сущностей, поэтому вы можете заменить $this->getEntityManager()->getConnection()->createQueryBuilder() на $em->createQueryBuilder()

Вы могли бы сделать что-то вроде

$qb = $this->createQueryBuilder()
    ->delete('AppBundle:Contact', 'c')                
    ->where('c.guid in (:guids)')
    ->setParameter(':guids', $guids);

А если вы хотите войти / выполнить

$query = $qb->getQuery();
log($query->getSql());
$query->execute();

Вам также не нужно добавлять beginTransaction и rollback, если запрос завершится неудачно и будет сгенерировано исключение, доктрина автоматически откатится.

0 голосов
/ 26 апреля 2018

первый. Проблема. Измените строку setParameter на следующую, которую вам не нужно использовать: в имени параметра.

->setParameter('guids', $guids);

Вторая проблема - вам не следует использовать настоящее имя таблицы, если вы имеете дело с queryBuilder.

Третья проблема - ваша логика неверна. Если вы хотите удалить один, то

$qb = $this->getEntityManager()->createQueryBuilder()
    ->delete('AppBundle:Contact', 'c')                
    ->where('c.guid = :guid)')
    ->setParameter('guid', $guids[0]);

Дополнительно

Я действительно не знаю, какую версию доктрины вы используете, но

$this->getEntityManager()->getConnection()->createQueryBuilder() - кажется неправильным, потому что обычно вы получаете соединение, если хотите выполнить RAW SQL.

Попробуйте изменить на

$qb = $this->getEntityManager()->createQueryBuilder()

И вам нужно использовать скобки вокруг переменной, только если это массив. Проверьте код ниже

$queryBuilder->andWhere('r.id IN (:ids)')
             ->setParameter('ids', $ids);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...