Остерегайтесь усеченных столов
Остерегайтесь усеченных таблиц в любой СУБД, особенно если вы хотите использовать явные транзакции для функции фиксации / отката.
Операторы DDL выполняют неявную фиксацию
Операторы усеченной таблицы являются операторами языка определения данных (DDL), и поэтому Операторы усеченной таблицы вызывают неявное COMMIT
для базы данных при их выполнении . Если вы выполняете TABLE TRUNCATE
, то база данных неявно фиксируется - даже если TABLE TRUNCATE
находится внутри оператора START TRANSACTION
- ваша таблица будет усечена, а ROLLBACK
будет не восстанавливать это.
Поскольку операторы усеченной таблицы выполняют неявные коммиты, Ответ Maxence не работает должным образом (но это не так, потому что вопрос был «как усечь таблицу»). Его ответ не работает должным образом, поскольку он усекает таблицу в блоке try
и предполагает, что таблица может быть восстановлена в блоке catch
, если что-то пойдет не так. Это неверное предположение.
Комментарии других пользователей в этой теме
ChrisAelbrecht не удалось заставить решение Maxence работать должным образом, потому что вы не можете откатить оператор таблицы усечения, даже если оператор таблицы усечения находится в явной транзакции.
user2130519, к сожалению, был понижен (-1, пока я не проголосовал) за предоставление правильного ответа - хотя он сделал это без обоснования своего ответа, что похоже на выполнение математики без показа вашей работы.
Моя рекомендация DELETE FROM
Я рекомендую использовать DELETE FROM
. В большинстве случаев он будет работать так, как ожидает разработчик. Но DELETE FROM
также не имеет недостатков - вы должны явно сбросить значение автоинкремента для таблицы. Чтобы сбросить значение автоматического приращения для таблицы, вы должны использовать другой оператор DDL - ALTER TABLE
- и, опять же, не использовать ALTER TABLE
в своем блоке try
. Это не будет работать, как ожидалось.
Если вы хотите узнать, когда следует использовать DELETE FROM
против TRUNCATE
, см. Плюсы и минусы TRUNCATE против 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');
Как удалить таблицу с возможностью отката / фиксации.
Но, если вы хотите использовать функцию отката / фиксации, вы должны использовать 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
.