Pozor na zkracování tabulek
Dejte si pozor na ořezávání tabulek v jakémkoli RDBMS, zvláště pokud chcete použít explicitní transakce pro funkci potvrzení/vrácení. Přečtěte si prosím 'Moje doporučení' této odpovědi.
Příkazy DDL provádějí implicitní potvrzení
Příkazy zkrácené tabulky jsou příkazy jazyka definice dat (DDL) a jako takové příkazy zkrácení tabulky spouštějí implicitní příkaz COMMIT
do databáze při jejich provedení . Pokud provedete TABLE TRUNCATE
pak je databáze implicitně vázána – i když TABLE TRUNCATE
je v rámci START TRANSACTION
příkaz -- vaše tabulka bude zkrácena a ROLLBACK
nebude obnovit.
Protože příkazy zkrácené tabulky provádějí implicitní potvrzení, Maxenceova odpověď nefunguje podle očekávání (ale není to špatně, protože otázka zněla "jak zkrátit tabulku"). Jeho odpověď nefunguje podle očekávání, protože ořezává tabulku v try
blok a předpokládá, že tabulku lze obnovit v catch
blokovat, pokud se něco pokazí. Toto je nesprávný předpoklad.
Komentáře a zkušenosti ostatních uživatelů v tomto vláknu
ChrisAelbrecht nedokázal zajistit, aby řešení Maxence správně fungovalo, protože příkaz truncate table nelze vrátit zpět, i když je příkaz truncate table v explicitní transakci.
user2130519, bohužel, dostal záporný hlas (-1, dokud jsem nehlasoval proti) za poskytnutí správné odpovědi – ačkoli tak učinil, aniž by svou odpověď zdůvodnil, což je jako dělat matematiku, aniž byste ukázali svou práci.
Moje doporučení DELETE FROM
Moje doporučení je použít DELETE FROM
. Ve většině případů bude fungovat tak, jak vývojář očekává. Ale DELETE FROM
nepřichází bez nevýhod - musíte explicitně resetovat hodnotu automatického přírůstku pro tabulku. Chcete-li resetovat hodnotu automatického přírůstku pro tabulku, musíte použít jiný příkaz DDL --ALTER TABLE
--a znovu nepoužívejte ALTER TABLE
ve vašem try
blok. Nebude to fungovat podle očekávání.
Pokud chcete tipy, kdy byste měli použít DELETE FROM
vs TRUNCATE
viz Výhody a nevýhody TRUNCATE vs DELETE FROM .
Pokud opravdu musíte, zde je návod, jak zkrátit
Nyní, se vším, co bylo řečeno. Pokud opravdu chcete zkrátit tabulku pomocí Doctrine2, použijte toto:(Níže je část Maxenceovy odpovědi, která tabulku správně zkrátí)
$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');
Jak odstranit tabulku s funkcí vrácení/potvrzení.
Pokud však chcete funkci vrácení/potvrzení, musíte použít DELETE FROM
:(Níže je upravená verze Maxenceovy odpovědi.)
$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();
}
Pokud potřebujete resetovat hodnotu automatického přírůstku, nezapomeňte zavolat ALTER TABLE <tableName> AUTO_INCREMENT = 1
.