Пазете се от съкращаване на таблици
Пазете се от съкращаване на таблици във всяка RDBMS, особено ако искате да използвате изрични транзакции за функционалност за записване/връщане. Моля, прочетете „Моята препоръка“ на този отговор.
DDL операторите изпълняват имплицитно извършване
Инструкциите за съкращаване на таблицата са изрази на езика за дефиниране на данни (DDL) и като такива изразите за съкращаване на таблицата задействат неявно COMMIT
към базата данни при изпълнението имта . Ако изпълните TABLE TRUNCATE
тогава базата данни е имплицитно ангажирана - дори ако TABLE TRUNCATE
е в рамките на START TRANSACTION
оператор--вашата таблица ще бъде съкратена и ROLLBACK
ще не възстановете го.
Тъй като изразите за съкращаване на таблицата изпълняват неявни комити, отговорът на Максънс не работи според очакванията (но не е грешно, защото въпросът беше "как да съкратим таблица"). Отговорът му не работи според очакванията, защото съкращава таблицата в try
блок и приема, че таблицата може да бъде възстановена в catch
блокирайте, ако нещо се обърка. Това е неправилно предположение.
Коментари и опит на други потребители в тази тема
ChrisAelbrecht не успя да накара решението на Maxence да работи правилно, тъй като не можете да върнете обратно оператор за truncate table, дори ако операторът за truncate table е в изрична транзакция.
user2130519, за съжаление, беше гласуван против (-1, докато не гласувах за) за предоставянето на правилния отговор – въпреки че го направи, без да обоснове отговора си, което е като да правиш математика, без да показваш работата си.
Моята препоръка DELETE FROM
Моята препоръка е да използвате DELETE FROM
. В повечето случаи той ще работи според очакванията на разработчика. Но DELETE FROM
не идва и без недостатъци - трябва изрично да нулирате стойността за автоматично увеличение за таблицата. За да нулирате стойността на автоматично увеличение за таблицата, трябва да използвате друг оператор DDL--ALTER TABLE
--и отново не използвайте ALTER TABLE
във вашия try
блок. Няма да работи според очакванията.
Ако искате съвети кога трябва да използвате DELETE FROM
срещу TRUNCATE
вижте Плюсите и минусите на TRUNCATE срещу DELETE FROM .
Ако наистина трябва, ето как да съкратите
Сега, с всичко казано. Ако наистина искате да съкратите таблица с помощта на Doctrine2, използвайте това:(По-долу е частта от отговора на Maxence, която правилно съкращава таблица)
$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');
Как да изтрия таблица с функция за връщане назад/коммит.
Но ако искате функционалност за връщане назад/коммит, трябва да използвате DELETE FROM
:(По-долу е модифицирана версия на отговора на Максънс.)
$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();
}
Ако трябва да нулирате стойността на автоматично увеличение, не забравяйте да извикате ALTER TABLE <tableName> AUTO_INCREMENT = 1
.