Uważaj na obcinanie tabel
Uważaj na obcinanie tabel w każdym RDBMS, zwłaszcza jeśli chcesz użyć jawnych transakcji do funkcji zatwierdzania/wycofywania. Przeczytaj „Moje rekomendacje” tej odpowiedzi.
Instrukcje DDL wykonują niejawne zatwierdzenie
Instrukcje obcinania tabeli to instrukcje języka definicji danych (DDL) i jako takie instrukcje obcinania tabeli wyzwalają niejawne COMMIT
do bazy danych po ich wykonaniu . Jeśli wykonasz TABLE TRUNCATE
wtedy baza danych jest niejawnie zatwierdzana — nawet jeśli TABLE TRUNCATE
znajduje się w START TRANSACTION
instrukcja--Twoja tabela zostanie obcięta, a ROLLBACK
nie przywróć go.
Ponieważ instrukcje obcinania tabeli wykonują niejawne zatwierdzenia, odpowiedź Maxence nie działa zgodnie z oczekiwaniami (ale to nie jest złe, bo pytanie brzmiało „jak obciąć tabelę”). Jego odpowiedź nie działa zgodnie z oczekiwaniami, ponieważ obcina tabelę w try
i zakłada, że tabela może zostać przywrócona w catch
zablokować, jeśli coś pójdzie nie tak. To błędne założenie.
Komentarze i doświadczenia innych użytkowników w tym wątku
ChrisAelbrecht nie był w stanie sprawić, by rozwiązanie Maxence działało poprawnie, ponieważ nie można wycofać instrukcji truncate table, nawet jeśli instrukcja truncate table jest w jawnej transakcji.
user2130519 został niestety przegłosowany (-1, dopóki nie oddałem głosu) za podanie poprawnej odpowiedzi — chociaż zrobił to bez uzasadnienia swojej odpowiedzi, co jest jak robienie matematyki bez pokazywania swojej pracy.
Moja rekomendacja DELETE FROM
Zalecam użycie DELETE FROM
. W większości przypadków będzie działać zgodnie z oczekiwaniami dewelopera. Ale DELETE FROM
nie jest też pozbawiony wad — należy jawnie zresetować wartość automatycznego przyrostu tabeli. Aby zresetować wartość automatycznego przyrostu tabeli, musisz użyć innej instrukcji DDL — ALTER TABLE
--i znowu nie używaj ALTER TABLE
w swoim try
blok. Nie będzie działać zgodnie z oczekiwaniami.
Jeśli potrzebujesz wskazówek, kiedy powinieneś użyć DELETE FROM
w porównaniu z TRUNCATE
zobacz Wady i zalety TRUNCATE vs DELETE FROM .
Jeśli naprawdę musisz, oto jak skrócić
Teraz, z tym wszystkim, co zostało powiedziane. Jeśli naprawdę chcesz obciąć tabelę za pomocą Doctrine2, użyj tego:(Poniżej znajduje się część odpowiedzi Maxence, która poprawnie obcina tabelę)
$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 usunąć tabelę z funkcją wycofywania/zatwierdzania.
Ale jeśli potrzebujesz funkcji wycofywania/zatwierdzania, musisz użyć DELETE FROM
:(Poniżej znajduje się zmodyfikowana wersja odpowiedzi Maxence'a.)
$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();
}
Jeśli potrzebujesz zresetować wartość automatycznego przyrostu, pamiętaj, aby wywołać ALTER TABLE <tableName> AUTO_INCREMENT = 1
.