mysql rollback by error HANDLER not working - mysql

I just build a stored procedure to test transaction in mysql.
But somehow it's not working.
Here is my code:
USE `test`;
DROP procedure IF EXISTS `testTran`;
DELIMITER $$
USE `test`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `testTran`()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION rollback;
START TRANSACTION;
INSERT INTO `test`.`books`(`name`,`number`) VALUES ('asd', 20);
ALTER TABLE `test`.`books` ADD COLUMN `name` VARCHAR(45) NULL AFTER `number` ;
COMMIT;
END$$
DELIMITER ;
Inside transaction, the second command is create an exist column which will be fail. What I expect is the first insert will be rollback. But actually, it's not. The insert do work.
Can anyone help?

In order to use transactions you need to convert the tables to a transaction table like InnoDB.
Optionally, you can rollback changes made by your stored procedure using SAVEPOINT.
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK TO identifier;
SAVEPOINT identifier;
START TRANSACTION;
INSERT INTO `test`.`books`(`name`,`number`) VALUES ('asd', 20);
ALTER TABLE `test`.`books` ADD COLUMN `name` VARCHAR(45) NULL AFTER `number` ;
COMMIT;

The ALTER TABLE statement causes an implicit COMMIT before it is executed.

Related

Rollback Stored procedure Call is not working in the mySQL

I have created a student table.
CREATE TABLE `student` (
`id` int DEFAULT NULL,
`name` varchar(5) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
I have created a stored procedure inserting the data.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_studentinsert1`(in_id int, in_name varchar(5),inn_id int, inn_name varchar(10))
BEGIN
DECLARE `_rollback` BOOL DEFAULT 0;
DECLARE exit HANDLER FOR SQLEXCEPTION
begin
ROLLBACK;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'SQLError occured. Triggered ROLLBACK';
select 'err' as message;
-- ERROR
end;
start transaction;
insert into student(id,name) values(in_id,in_name);
INSERT INTO student(id,name) values(inn_id,inn_name);
commit;
select * from student;
END$$
DELIMITER ;
. I have written two insert queries inside of stored procedure. I have given first two input parameters valid data, For 2nd record , I have given invalid data, once run the sp, first record inserted & 2nd record exception happen but once exception happen , 1st record rollback not happen.
Please help me.

MySQL SP with transaction correct syntax with in parameters

To quite simply put how my SP looks it is basically like this atleast syntax wise
DELIMITER $$
DROP PROCEDURE IF EXISTS `info_insert_or_update` $$
CREATE PROCEDURE `info_insert_or_update` (
IN in_id bigint,
IN in_name varchar(150),
IN in_details varchar(150))
START TRANSACTION;
INSERT INTO infos (id, name)
VALUES (in_id, in_name)
ON DUPLICATE KEY UPDATE name = in_name;
INSERT INTO details (details_id, details)
VALUES(in_id,
in_details)
ON DUPLICATE KEY UPDATE details = in_details;
COMMIT;
END$$
DELIMITER ;
With this the problem is that it cant recognize the in_ variables and i understand that that is because i need an compound statement with BEGIN END around everything but where ever i seem to put it it is something wrong with the syntax. So what is the correct syntax when i got this type of SP with in parameters that then has an transaction? (want transaction as i will add rollback onto it as well)
You are missing datatype for the in_details-parameter and you are missing the starting BEGIN
DELIMITER $$
DROP PROCEDURE IF EXISTS `info_insert_or_update`
$$
CREATE PROCEDURE `info_insert_or_update` (
in_id bigint,
in_name varchar(150),
in_details varchar(150)
)
BEGIN
START TRANSACTION;
INSERT INTO infos (id, name)
VALUES (in_id, in_name)
ON DUPLICATE KEY UPDATE name = in_name;
INSERT INTO details (details_id, details)
VALUES(in_id, in_details)
ON DUPLICATE KEY UPDATE details = in_details;
COMMIT;
END
$$

MySQL stored procedure for table insert error

I have below basic table:
create table hobbies (
id int primary key auto_increment,
name varchar(32) unique);
And I am trying to create a stored procedure to insert a new row in this table, like below:
delimiter //
create procedure add_hobby(hobby varchar(32))
begin
insert into hobbies(name) values(hobby);
end
delimiter //
call add_hobby('randomHobby');
When I call the procedure like above I am getting message "An unexpected error occured". I am running the queries on db-fiddle.com, MySQL ver 8.0. Could anyone offer some guidance if I've done something wrong or missed something? I can mention that procedure with select operation and no parameters works. Many thanks in advance.
You need to set your delimiter to begin with and then reset it at the end
for your parameters you need to set weather they are IN or out then the name and the type
delimiter //
create procedure add_hobby(IN hobby varchar(32))
begin
insert into hobbies(name) values(hobby);
end//
delimiter ;

Rollback without START TRANSACTION statement is not working in MySQL Stored Procedure

I am using mysql v5.6.
After inserting duplicate record in users table through stored procedure It throws an exception and this is good but unable to rollback for table POSTS.
Here is SQL codes for SP :
DELIMITER //
CREATE PROCEDURE usp_add_user_tests
( IN `i_name` VARCHAR(50),
IN `i_email` VARCHAR(100),
IN `i_status` TINYINT(1) UNSIGNED,
OUT `p_sqlcode` INT(11) UNSIGNED,
OUT `p_status_message` VARCHAR(100)
)
MODIFIES SQL DATA
BEGIN
DECLARE duplicate_key CONDITION FOR 1062;
DECLARE EXIT HANDLER FOR duplicate_key
BEGIN SET p_sqlcode=1062; SET p_status_message='Duplicate key error';
ROLLBACK ;
END;
SET p_sqlcode=0;
INSERT INTO posts (title)
VALUES('test');
INSERT INTO users (name,email,status)
VALUES(i_name,i_email,i_status);
IF p_sqlcode<>0 THEN
SET p_status_message=CONCAT(p_status_message,' when inserting new user');
ELSE
SET p_status_message='Success';
END IF;
END //
DELIMITER ;
Is it possible to rollback for table posts without using Start Transaction statement.
I don't think you have actually started a "transaction". I am pretty sure that you need to implement one of the mechanisms listed here: https://dev.mysql.com/doc/refman/5.7/en/commit.html

MySQL 5.6 GET DIAGNOSTICS into log table and ROLLBACK previous DML

Apparently I cannot combine the GET DIAGNOSTICS and ROLLBACK statements inside a stored procedure: besides catching the error, I want to be able to reverse all the previous processed data, not just to stop the execution. Please find bellow my script:
Create the log table:
CREATE TABLE tbl_logs (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`txt` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`));
Create the stored procedure:
DELIMITER $$
CREATE PROCEDURE `test`()
BEGIN
DECLARE state CHAR(5) DEFAULT ’00000′;
DECLARE msg TEXT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
begin
rollback;
GET DIAGNOSTICS CONDITION 1 state = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
insert into tbl_logs (txt) select concat(‘Error ‘,state,’: ‘,msg);
end;
start transaction;
insert into tbl_logs (txt) select state;
– drop table no_such_table;
insert into tbl_logs (txt) select ‘commit’;
commit;
END
call the procedure:
call test();
select * from tbl_logs;
=> check the table: 2 rows
00000
commit
Alter the procedure:
Take the comment out, making the drop table visible.
call the procedure:
call test();
select * from tbl_logs;
=> check the table: 2 new rows instead of just one, the last
00000
Error 42S02: Unknown table ‘no_such_table’
=> the handler catches the error and stops the execution, is just that doesn’t consider the rollback (no matter what/where other DML are previously made, they are committed)…
What am I doing wrong?
As documented under DROP TABLE Syntax:
Note 
DROP TABLE automatically commits the current active transaction, unless you use the TEMPORARY keyword.