Se upp för trunkering av tabeller
Akta dig för att trunkera tabeller i alla RDBMS, speciellt om du vill använda explicita transaktioner för commit/rollback-funktionalitet. Läs "Min rekommendation" i detta svar.
DDL-satser utför en implicit commit
Trunkerat tabellsatser är DDL-satser (Data Definition Language), och som sådana utlöser Truncate table-satser en implicit COMMIT
till databasen när de körs . Om du utför en TABLE TRUNCATE
då är databasen implicit förpliktad till--även om TABLE TRUNCATE
är inom en START TRANSACTION
uttalande--din tabell kommer att trunkeras och en ROLLBACK
kommer inte återställ det.
Eftersom trunkerade tabellsatser utför implicita bekräftelser, fungerar Maxences svar inte som förväntat (men det är inte fel, för frågan var "hur man trunkerar en tabell"). Hans svar fungerar inte som förväntat eftersom det trunkerar tabellen i ett try
block, och antar att tabellen kan återställas i catch
blockera, om något går fel. Detta är ett felaktigt antagande.
Andra användares kommentarer och erfarenheter i den här tråden
ChrisAelbrecht kunde inte få Maxences lösning att fungera korrekt eftersom du inte kan återställa en trunkeringstabellsats, även om trunkeringstabellsatsen är i en explicit transaktion.
user2130519 blev tyvärr nedröstad (-1 tills jag röstade upp) för att ha angett rätt svar – även om han gjorde det utan att motivera sitt svar, vilket är som att göra matematik utan att visa ditt arbete.
Min rekommendation DELETE FROM
Min rekommendation är att använda DELETE FROM
. I de flesta fall kommer det att fungera som utvecklaren förväntar sig. Men, DELETE FROM
kommer inte utan nackdelar heller - du måste uttryckligen återställa värdet för automatisk inkrement för tabellen. För att återställa det automatiska ökningsvärdet för tabellen måste du använda en annan DDL-sats--ALTER TABLE
--och återigen, använd inte ALTER TABLE
i ditt try
blockera. Det kommer inte att fungera som förväntat.
Om du vill ha tips om när du ska använda DELETE FROM
kontra TRUNCATE
se För- och nackdelar med TRUNCATE vs DELETE FROM
a> .
Om du verkligen måste, här är hur du trunkerar
Nu med allt som sagt. Om du verkligen vill trunkera en tabell med Doctrine2, använd detta:(Nedan är den del av Maxences svar som korrekt trunkerar en tabell)
$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');
Hur man tar bort en tabell med rollback/commit-funktion.
Men om du vill ha rollback/commit-funktionalitet måste du använda DELETE FROM
:(Nedan är en modifierad version av Maxences svar.)
$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();
}
Om du behöver återställa värdet för automatisk ökning, kom ihåg att anropa ALTER TABLE <tableName> AUTO_INCREMENT = 1
.