Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment tronquer une table en utilisant Doctrine 2 ?

Méfiez-vous des tableaux tronqués

Méfiez-vous des tables tronquées dans n'importe quel SGBDR, en particulier si vous souhaitez utiliser des transactions explicites pour la fonctionnalité de validation/annulation. Veuillez lire la "Ma recommandation" de cette réponse.

Les instructions DDL effectuent un commit implicite

Les instructions de table tronquée sont des instructions en langage de définition de données (DDL) et, en tant que telles, les instructions truncate table déclenchent un COMMIT implicite à la base de données lors de leur exécution . Si vous effectuez un TABLE TRUNCATE alors la base de données est implicitement validée - même si le TABLE TRUNCATE est dans un START TRANSACTION instruction--votre table sera tronquée et un ROLLBACK ne va pas restaurez-le.

Étant donné que les instructions truncate table effectuent des commits implicites, la réponse de Maxence ne fonctionne pas comme prévu (mais ce n'est pas faux, car la question était "comment tronquer une table"). Sa réponse ne fonctionne pas comme prévu car elle tronque le tableau dans un try bloc, et suppose que la table peut être restaurée dans le catch bloquer, si quelque chose ne va pas. C'est une hypothèse incorrecte.


Commentaires et expériences d'autres utilisateurs dans ce fil

ChrisAelbrecht n'a pas pu faire fonctionner correctement la solution de Maxence, car vous ne pouvez pas annuler une instruction truncate table, même si l'instruction truncate table se trouve dans une transaction explicite.

user2130519, malheureusement, a été déclassé (-1 jusqu'à ce que j'aie voté pour) pour avoir fourni la bonne réponse - bien qu'il l'ait fait sans justifier sa réponse, ce qui revient à faire des maths sans montrer votre travail.


Ma recommandation DELETE FROM

Ma recommandation est d'utiliser DELETE FROM . Dans la plupart des cas, il fonctionnera comme prévu par le développeur. Mais, DELETE FROM n'est pas non plus sans inconvénients - vous devez explicitement réinitialiser la valeur d'incrémentation automatique de la table. Pour réinitialiser la valeur d'incrémentation automatique de la table, vous devez utiliser une autre instruction DDL :ALTER TABLE --et, encore une fois, n'utilisez pas ALTER TABLE dans votre try bloc. Cela ne fonctionnera pas comme prévu.

Si vous voulez des conseils sur le moment où vous devez utiliser DELETE FROM vs TRUNCATE voir Avantages et inconvénients de TRUNCATE vs DELETE FROM .


Si vous le devez vraiment, voici comment tronquer

Maintenant, avec tout ce qui a été dit. Si vous voulez vraiment tronquer un tableau en utilisant Doctrine2, utilisez ceci :(Ci-dessous, la partie de la réponse de Maxence qui tronque correctement un tableau)

$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');


Comment supprimer une table avec la fonctionnalité rollback/commit.

Mais, si vous voulez la fonctionnalité rollback/commit, vous devez utiliser DELETE FROM :(Ci-dessous une version modifiée de la réponse de 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();
}

Si vous devez réinitialiser la valeur d'incrémentation automatique, n'oubliez pas d'appeler ALTER TABLE <tableName> AUTO_INCREMENT = 1 .