Pas op voor het afkappen van tabellen
Pas op voor het afkappen van tabellen in een RDBMS, vooral als u expliciete transacties wilt gebruiken voor commit/rollback-functionaliteit. Lees de 'Mijn aanbeveling' van dit antwoord.
DDL-statements voeren een impliciete verplichting uit
Truncate-tabelinstructies zijn DDL-instructies (Data Definition Language), en als zodanig veroorzaken Truncate Table-instructies een impliciete COMMIT
naar de database na hun uitvoering . Als u een TABLE TRUNCATE
. uitvoert dan is de database impliciet toegewijd aan--zelfs als de TABLE TRUNCATE
is binnen een START TRANSACTION
statement--uw tabel wordt afgekapt en een ROLLBACK
zal niet herstel het.
Omdat truncate table-statements impliciete commits uitvoeren, werkt Maxence's antwoord niet zoals verwacht (maar het is niet verkeerd, want de vraag was "hoe een tabel af te kappen"). Zijn antwoord presteert niet zoals verwacht omdat het de tabel afkapt in een try
blok, en gaat ervan uit dat de tabel kan worden hersteld in de catch
blokkeren, als er iets misgaat. Dit is een onjuiste veronderstelling.
Opmerkingen en ervaringen van andere gebruikers in deze thread
ChrisAelbrecht kon de oplossing van Maxence niet goed laten werken, omdat u een instructie voor het afkappen van een tabel niet kunt terugdraaien, zelfs niet als het instructie voor het afkappen van een tabel zich in een expliciete transactie bevindt.
user2130519 werd helaas gedownvote (-1 totdat ik upvote) voor het geven van het juiste antwoord - hoewel hij dit deed zonder zijn antwoord te rechtvaardigen, wat net zoiets is als wiskunde doen zonder je werk te laten zien.
Mijn aanbeveling DELETE FROM
Mijn aanbeveling is om DELETE FROM
. te gebruiken . In de meeste gevallen zal het presteren zoals de ontwikkelaar verwacht. Maar, DELETE FROM
komt ook niet zonder nadelen - u moet de auto-incrementwaarde voor de tabel expliciet opnieuw instellen. Om de auto-incrementwaarde voor de tabel opnieuw in te stellen, moet u een andere DDL-instructie gebruiken--ALTER TABLE
--en, nogmaals, gebruik ALTER TABLE
niet in je try
blok. Het werkt niet zoals verwacht.
Als je tips wilt over wanneer je DELETE FROM
. moet gebruiken vs TRUNCATE
zie Voor- en nadelen van TRUNCATE versus DELETE FROM .
Als het echt moet, kun je dit als volgt afkappen
Nu, met dat alles gezegd. Als je een tabel echt wilt afkappen met Doctrine2, gebruik dan dit:(Hieronder staat het gedeelte van Maxence's antwoord dat een tabel correct afkapt)
$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');
Hoe een tabel te verwijderen met rollback/commit-functionaliteit.
Maar als u een rollback/commit-functionaliteit wilt, moet u DELETE FROM
gebruiken :(Hieronder staat een aangepaste versie van het antwoord van 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();
}
Als u de waarde voor automatisch verhogen moet resetten, vergeet dan niet om ALTER TABLE <tableName> AUTO_INCREMENT = 1
aan te roepen. .