Pas på afkortning af tabeller
Pas på med at afkorte tabeller i enhver RDBMS, især hvis du vil bruge eksplicitte transaktioner til commit/rollback-funktionalitet. Læs venligst 'Min anbefaling' i dette svar.
DDL-sætninger udfører en implicit commit
Truncate table statements er data definition language (DDL) sætninger, og som sådan udløser truncate table statements en implicit COMMIT
til databasen efter deres udførelse . Hvis du udfører en TABLE TRUNCATE
så er databasen implicit forpligtet til - også selvom TABLE TRUNCATE
er inden for en START TRANSACTION
statement--din tabel vil blive afkortet og en ROLLBACK
vil ikke gendan det.
Fordi trunkerede tabelsætninger udfører implicitte commits, fungerer Maxences svar ikke som forventet (men det er ikke forkert, for spørgsmålet var "hvordan man afkorter en tabel"). Hans svar fungerer ikke som forventet, fordi det afkorter tabellen i et try
blok, og antager, at tabellen kan gendannes i catch
blokere, hvis noget går galt. Dette er en forkert antagelse.
Andre brugeres kommentarer og erfaringer i denne tråd
ChrisAelbrecht var ude af stand til at få Maxences løsning til at fungere korrekt, fordi du ikke kan rulle tilbage en trunkeret tabel-sætning, selvom den trunkerede tabel-sætning er i en eksplicit transaktion.
user2130519 blev desværre nedstemt (-1, indtil jeg stemte op) for at give det rigtige svar – selvom han gjorde det uden at begrunde sit svar, hvilket er som at lave matematik uden at vise dit arbejde.
Min anbefaling DELETE FROM
Min anbefaling er at bruge DELETE FROM
. I de fleste tilfælde vil det fungere, som udvikleren forventer. Men DELETE FROM
kommer heller ikke uden ulemper - du skal udtrykkeligt nulstille den automatiske stigningsværdi for tabellen. For at nulstille den automatiske stigningsværdi for tabellen skal du bruge en anden DDL-sætning--ALTER TABLE
--og igen, brug ikke ALTER TABLE
i dit try
blok. Det vil ikke fungere som forventet.
Hvis du vil have tips til, hvornår du skal bruge DELETE FROM
vs TRUNCATE
se Fordele og ulemper ved TRUNCATE vs DELETE FROM
a> .
Hvis du virkelig skal, kan du afkorte sådan her
Nu med alt det sagt. Hvis du virkelig ønsker at afkorte en tabel ved hjælp af Doctrine2, så brug denne:(Nedenfor er den del af Maxences svar, der korrekt trunkerer en 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');
Sådan sletter du en tabel med rollback/commit-funktionalitet.
Men hvis du ønsker rollback/commit funktionalitet, skal du bruge DELETE FROM
:(Nedenfor er en modificeret version af 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();
}
Hvis du har brug for at nulstille den automatiske stigningsværdi, skal du huske at kalde ALTER TABLE <tableName> AUTO_INCREMENT = 1
.