Как обрезать таблицу с помощью Doctrine 2?

Я предполагаю, что мне нужно создать собственный запрос для обрезания таблицы с помощью Doctine2.

$emptyRsm = new \Doctrine\ORM\Query\ResultSetMapping(); $sql = 'TRUNCATE TABLE Article'; $query = em()->createNativeQuery($sql, $emptyRsm); $query->execute(); 

Это дает ошибку

 SQLSTATE[HY000]: General error 

Что мне нужно изменить для моего кода, чтобы сделать эту работу?

Solutions Collecting From Web of "Как обрезать таблицу с помощью Doctrine 2?"

Остерегайтесь усекающих таблиц

Остерегайтесь усечения таблиц в любой СУБД, особенно если вы хотите использовать явные транзакции для функций фиксации / отката.

Заявления DDL выполняют неявное

Операторы таблицы обрезания – это операторы языка определения данных (DDL), и, поскольку такие инструкции таблицы усечения запускают неявный COMMIT в базу данных после их выполнения . Если вы выполняете TABLE TRUNCATE тогда база данных неявно передается – даже если TABLE TRUNCATE находится в инструкции START TRANSACTION – ваша таблица будет усечена, а ROLLBACK не восстановит ее.

Поскольку инструкции таблицы truncate выполняют неявные коммиты, ответ Maxence не выполняется так, как ожидалось (но это не так, потому что вопрос был «как обрезать таблицу»). Его ответ не выполняется так, как ожидалось, потому что он обрезает таблицу в блоке try и предполагает, что таблица может быть восстановлена ​​в блоке catch , если что-то пойдет не так. Это неверное предположение.

Другие комментарии пользователя и опыт в этой теме

ChrisAelbrecht не смог заставить решение Maxence работать должным образом, потому что вы не можете отменить инструкцию таблицы truncate, даже если инструкция таблицы truncate находится в явной транзакции.

user2130519, к сожалению, был downvoted (-1 до тех пор, пока я не был поддержан) для обеспечения правильного ответа – хотя он сделал это, не оправдывая свой ответ, который похож на математику, не показывая вашу работу.

Моя рекомендация DELETE FROM

Моя рекомендация – использовать DELETE FROM . В большинстве случаев он будет выполняться по мере того, как ожидает разработчик. Но DELETE FROM не имеет недостатков – вы должны явно сбросить значение автоматического приращения для таблицы. Чтобы сбросить значение автоматического увеличения для таблицы, вы должны использовать другой оператор DDL – ALTER TABLE – и, опять же, не используйте ALTER TABLE в блоке try . Он не будет работать так, как ожидалось.

Если вам нужны подсказки, когда вы должны использовать DELETE FROM vs TRUNCATE см. « Плюсы и минусы» TRUNCATE vs DELETE FROM .

Если вам действительно нужно, вот как усечь

Теперь, со всем, что сказал. Если вы действительно хотите обрезать таблицу с помощью Doctrine2, используйте это: (Ниже приведена часть ответа Maxence, которая правильно обрезает таблицу)

 $cmd = $em->getClassMetadata($className); $connection = $em->getConnection(); $dbPlatform = $connection->getDatabasePlatform(); $connection->query('SET FOREIGN_KEY_CHECKS=0'); $q = $dbPlatform->getTruncateTableSql($cmd->getTableName()); $connection->executeUpdate($q); $connection->query('SET FOREIGN_KEY_CHECKS=1'); 

Как удалить таблицу с функцией rollback / commit.

Но, если вам нужны функции отката / фиксации, вы должны использовать DELETE FROM : (Ниже приведена измененная версия ответа Maxence).

 $cmd = $em->getClassMetadata($className); $connection = $em->getConnection(); $connection->beginTransaction(); try { $connection->query('SET FOREIGN_KEY_CHECKS=0'); $connection->query('DELETE FROM '.$cmd->getTableName()); // Beware of ALTER TABLE here--it's another DDL statement and will cause // an implicit commit. $connection->query('SET FOREIGN_KEY_CHECKS=1'); $connection->commit(); } catch (\Exception $e) { $connection->rollback(); } 

Если вам нужно сбросить значение автоматического прироста, не забудьте вызвать ALTER TABLE <tableName> AUTO_INCREMENT = 1 .

Вот код, который я использую:

 $cmd = $em->getClassMetadata($className); $connection = $em->getConnection(); $dbPlatform = $connection->getDatabasePlatform(); $connection->beginTransaction(); try { $connection->query('SET FOREIGN_KEY_CHECKS=0'); $q = $dbPlatform->getTruncateTableSql($cmd->getTableName()); $connection->executeUpdate($q); $connection->query('SET FOREIGN_KEY_CHECKS=1'); $connection->commit(); } catch (\Exception $e) { $connection->rollback(); } 

Или вы можете просто попробовать это:

 $this->getEm()->createQuery('DELETE AcmeBundle:Post p')->execute(); 

Если у вас есть отношения, вы должны быть осторожны, чтобы обрабатывать связанные объекты.