Est-il possible de revenir en arrière automatiquement en cas d'erreur sur une liste de commandes mysql?
par exemple quelque chose comme:
begin transaction;
insert into myTable values1 ...
insert into myTable values2 ...; -- will throw an error
commit;
maintenant, lors de l'exécution, je veux que toute la transaction échoue, et donc je devrais PAS voir values1 dans myTable. mais malheureusement, la table est pupulée avec des valeurs1 même si la transaction comporte des erreurs.
des idées sur la façon de le faire revenir en arrière? (encore une fois, en cas d'erreur)?
EDIT - changé de DDL à SQL standard
Vous pouvez utiliser 13.6.7.2. DECLARE ... HANDLER Syntax de la manière suivante:
DELIMITER $$
CREATE PROCEDURE `sp_fail`()
BEGIN
DECLARE `_rollback` BOOL DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` = 1;
START TRANSACTION;
INSERT INTO `tablea` (`date`) VALUES (NOW());
INSERT INTO `tableb` (`date`) VALUES (NOW());
INSERT INTO `tablec` (`date`) VALUES (NOW()); -- FAIL
IF `_rollback` THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END$$
DELIMITER ;
Pour un exemple complet, vérifiez ce qui suit SQL Fiddle .
Vous pouvez utiliser EXIT HANDLER si vous avez par exemple besoin de SIGNALER une EXCEPTION SQL spécifique dans votre code. Par exemple:
DELIMITER $$
CREATE PROCEDURE `sp_fail`()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK; -- rollback any changes made in the transaction
RESIGNAL; -- raise again the sql exception to the caller
END;
START TRANSACTION;
insert into myTable values1 ...
IF fail_condition_meet THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Custom error detected.', MYSQL_ERRNO = 2000;
END IF;
insert into myTable values2 ... -- this will not be executed
COMMIT; -- this will not be executed
END$$
DELIMITER ;
La solution ci-dessus est bonne mais pour la rendre encore plus simple
DELIMITER $$
CREATE PROCEDURE `sp_fail`()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK; -- rollback any error in the transaction
END;
START TRANSACTION;
insert into myTable values1 ...
insert into myTable values2 ... -- Fails
COMMIT; -- this will not be executed
END$$
DELIMITER ;