テーブルの切り捨てに注意する
特にコミット/ロールバック機能に明示的なトランザクションを使用する場合は、RDBMS でのテーブルの切り捨てに注意してください。この回答の「私の推奨事項」をお読みください。
DDL ステートメントは暗黙的なコミットを実行します
Truncate table ステートメントはデータ定義言語 (DDL) ステートメントであり、そのため、truncate table ステートメントは実行時にデータベースへの暗黙的な をトリガーしCOMMIT
ます。a を実行するTABLE TRUNCATE
と、データベースは暗黙的にコミットされます。これがステートメントTABLE TRUNCATE
内にある場合でもSTART TRANSACTION
、テーブルは切り捨てられ、 aROLLBACK
は復元しません。
truncate table ステートメントは暗黙的なコミットを実行するため、Maxence の回答は期待どおりに実行されません(ただし、質問は「テーブルを切り捨てる方法」だったので、間違っていません)。彼の答えは、ブロック内のテーブルを切り捨て、何か問題が発生した場合try
にテーブルをブロック内で復元できると想定しているため、期待どおりに機能しません。catch
これは間違った仮定です。
このスレッドでの他のユーザーのコメントと経験
ChrisAelbrecht は Maxence のソリューションを適切に機能させることができませんでした。これは、truncate table ステートメントが明示的なトランザクション内にある場合でも、truncate table ステートメントをロールバックできないためです。
残念ながら、user2130519 は、正しい答えを提供したことで反対票を投じられました (私が賛成票を投じるまで -1)。
私のおすすめDELETE FROM
私のお勧めは、 を使用することDELETE FROM
です。ほとんどの場合、開発者の期待どおりに動作します。ただし、DELETE FROM
欠点がないわけではありません。テーブルの自動インクリメント値を明示的にリセットする必要があります。テーブルの自動インクリメント値をリセットするには、別の DDL ステートメントを使用する必要があります。また、ブロック内でALTER TABLE
は使用しないALTER TABLE
でください。try
期待どおりに動作しません。
いつ使用する必要があるかについてのヒントが必要な場合は、 DELETE FROM
TRUNCATEと 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');
ロールバック/コミット機能を使用してテーブルを削除する方法。
ただし、ロールバック/コミット機能が必要な場合は、次を使用する必要があります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
ください。