当心截断表
请注意在任何 RDBMS 中截断表,尤其是在要将显式事务用于提交/回滚功能时。请阅读此答案的“我的建议”。
DDL 语句执行隐式提交
截断表语句是数据定义语言 (DDL) 语句,因此截断表语句在执行时会触发对数据库的隐式 COMMIT
。如果执行 a,则数据库将隐式提交到 (即使 位于语句中),您的表将被截断,并且 a 将不会还原它。TABLE TRUNCATE
TABLE TRUNCATE
START TRANSACTION
ROLLBACK
由于截断表语句执行隐式提交,因此 Maxence 的答案不会按预期执行(但这并不错误,因为问题是“如何截断表”)。他的答案没有按预期执行,因为它截断了块中的表,并假设如果出现问题,可以在块中恢复表。这是一个不正确的假设。try
catch
其他用户在此线程中的评论和体验
ChrisAelbrecht 无法使 Maxence 的解决方案正常工作,因为您无法回滚截断表语句,即使截断表语句位于显式事务中也是如此。
不幸的是,user2130519因为提供正确的答案而被否决(-1直到我赞成) - 尽管他这样做没有证明他的答案,这就像在不显示你的工作的情况下做数学一样。
我的建议DELETE FROM
我的建议是使用.在大多数情况下,它将按照开发人员的预期执行。但是,也不是没有缺点 - 您必须显式重置表的自动增量值。若要重置表的自动增量值,必须使用另一个 DDL 语句----并且同样,不要在块中使用。它不会按预期工作。DELETE FROM
DELETE FROM
ALTER TABLE
ALTER TABLE
try
如果你想要关于何时应该使用 vs 查看 TRUNCATE vs DELETE FROM 的优缺点的提示。DELETE FROM
TRUNCATE
如果真的必须,请按以下步骤截断
现在,说了这么多。如果你真的想使用 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');
如何删除具有回滚/提交功能的表。
但是,如果你想要回滚/提交功能,你必须使用:(下面是Maxence答案的修改版本。DELETE FROM
$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