php - vaciar - truncate table mysql w3schools
¿Cómo truncar una tabla usando Doctrine 2? (4)
Supongo que necesito crear una consulta nativa para truncar una tabla usando Doctine2.
$emptyRsm = new /Doctrine/ORM/Query/ResultSetMapping();
$sql = ''TRUNCATE TABLE Article'';
$query = em()->createNativeQuery($sql, $emptyRsm);
$query->execute();
Esto da el error.
SQLSTATE[HY000]: General error
¿Qué necesito para cambiar mi código para que esto funcione?
Cuidado con las tablas de truncamiento
Tenga cuidado al truncar las tablas en cualquier RDBMS, especialmente si desea utilizar transacciones explícitas para la funcionalidad de confirmación / retrotracción.
Las declaraciones DDL realizan un compromiso implícito
Las sentencias de la tabla truncada son sentencias del lenguaje de definición de datos (DDL), y como tal , las sentencias de la tabla truncada activan un COMMIT
implícito en la base de datos una vez que se ejecutan . Si realiza una TABLE TRUNCATE
, la base de datos está comprometida implícitamente, incluso si TABLE TRUNCATE
está dentro de una instrucción START TRANSACTION
, su tabla se truncará y ROLLBACK
no la restaurará.
Debido a que las instrucciones de la tabla truncada realizan confirmaciones implícitas, la respuesta de Maxence no funciona como se esperaba (pero no está mal, porque la pregunta era "cómo truncar una tabla"). Su respuesta no funciona como se esperaba porque trunca la tabla en un bloque de try
y asume que la tabla se puede restaurar en el bloque catch
, si algo sale mal. Esta es una suposición incorrecta.
Comentarios y experiencias de otros usuarios en este hilo
ChrisAelbrecht no pudo lograr que la solución de Maxence funcionara correctamente porque no puede deshacer una declaración de la tabla de truncado, incluso si la declaración de la tabla de truncar está en una transacción explícita.
El usuario 2130519, desafortunadamente, fue votado a favor (-1 hasta que voté) por proporcionar la respuesta correcta, aunque lo hizo sin justificar su respuesta, que es como hacer matemáticas sin mostrar su trabajo.
Mi recomendación DELETE FROM
Mi recomendación es usar DELETE FROM
. En la mayoría de los casos, funcionará como el desarrollador espera. Sin embargo, DELETE FROM
tampoco viene sin inconvenientes: debe restablecer explícitamente el valor de incremento automático para la tabla. Para restablecer el valor de incremento automático para la tabla, debe usar otra declaración DDL: ALTER TABLE
y, nuevamente, no use ALTER TABLE
en su bloque try
. No funcionará como se esperaba.
Si desea obtener consejos sobre cuándo debe usar DELETE FROM
vs TRUNCATE
consulte Pros y Contras de TRUNCATE vs DELETE FROM .
Si realmente debes hacerlo, aquí tienes cómo truncar.
Ahora, con todo lo dicho. Si realmente desea truncar una tabla usando Doctrine2, use esto: (A continuación se encuentra la parte de la respuesta de Maxence que trunca correctamente una tabla)
$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'');
Cómo eliminar una tabla con funcionalidad rollback / commit.
Pero, si desea la funcionalidad de restauración / retroceso, debe usar DELETE FROM
: (A continuación se muestra una versión modificada de la respuesta 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 necesita restablecer el valor de incremento automático, recuerde llamar ALTER TABLE <tableName> AUTO_INCREMENT = 1
.
Aquí está el código que estoy usando:
$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$dbPlatform = $connection->getDatabasePlatform();
$connection->beginTransaction();
try {
$connection->query(''SET FOREIGN_KEY_CHECKS=0'');
$q = $dbPlatform->getTruncateTableSql($cmd->getTableName());
$connection->executeUpdate($q);
$connection->query(''SET FOREIGN_KEY_CHECKS=1'');
$connection->commit();
}
catch (/Exception $e) {
$connection->rollback();
}
Este es un ejemplo de método de truncamiento del rasgo en pruebas unitarias.
/**
* Cleanup any needed table abroad TRUNCATE SQL function
*
* @param string $className (example: App/Entity/User)
* @param EntityManager $em
* @return bool
*/
private function truncateTable (string $className, EntityManager $em): bool {
$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$connection->beginTransaction();
try {
$connection->query(''SET FOREIGN_KEY_CHECKS=0'');
$connection->query(''TRUNCATE TABLE ''.$cmd->getTableName());
$connection->query(''SET FOREIGN_KEY_CHECKS=1'');
$connection->commit();
$em->flush();
} catch (/Exception $e) {
try {
fwrite(STDERR, print_r(''Can/'t truncate table '' . $cmd->getTableName() . ''. Reason: '' . $e->getMessage(), TRUE));
$connection->rollback();
return false;
} catch (ConnectionException $connectionException) {
fwrite(STDERR, print_r(''Can/'t rollback truncating table '' . $cmd->getTableName() . ''. Reason: '' . $connectionException->getMessage(), TRUE));
return false;
}
}
return true;
}
Tenga en cuenta que si no usa $em->flush()
, corre el riesgo de tener un problema con la siguiente consulta de doctrina.
También debe comprender que si usa este método en un controlador, debe cambiar las líneas fwrite(STDERR, print_r(...
a algo que su servicio de registrador pueda usar.
O puedes probar esto:
$this->getEm()->createQuery(''DELETE AcmeBundle:Post p'')->execute();
Si tiene relaciones, debe tener cuidado de manejar las entidades vinculadas.