Why is this code not catching the error when I try to delete a row that doesn't exist? No matter what parameter I pass in as the name of the row, it always returns "1 row deleted" and doesn't use the exit handlers. which are supposed to catch just this type of error.
USE yoga;
DROP PROCEDURE IF EXISTS delete_warmup;
DELIMITER //
CREATE PROCEDURE delete_warmup
(
warmup_name_param VARCHAR(100)
)
BEGIN
DECLARE row_not_found TINYINT DEFAULT FALSE;
DECLARE sql_exception TINYINT DEFAULT FALSE;
BEGIN
DECLARE EXIT HANDLER FOR 1329
SET row_not_found = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET sql_exception = TRUE;
DELETE FROM warmup
WHERE warmup_name = warmup_name_param;
SELECT '1 row was deleted.' AS message;
END;
IF row_not_found = TRUE THEN
SELECT 'Row not deleted - row not found' AS message;
ELSEIF sql_exception = TRUE THEN
SHOW ERRORS;
END IF;
END//
DELIMITER ;
CALL delete_warmup ('Monkey business');
You are using an exit handler for a duplicate parameter: http://www.briandunning.com/errors/596 which is 1329 as you specified
Perhaps you should try error code 1011 : http://www.briandunning.com/errors/278
Also, try looking for NOT FOUND as well as SQLException
Also, try to put the exit handler outside the begin/end clause.
so your BEGIN and END clause would be
DECLARE EXIT HANDLER FOR 1011
DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND
BEGIN
SET row_not_found = TRUE;
SET sql_exception = TRUE;
DELETE FROM warmup
WHERE warmup_name = warmup_name_param;
SELECT '1 row was deleted.' AS message;
END;
Related
It's the first time I use cursors and im having issues with the variable 'done'. This variable handles whether the loop iterates over the cursosr or not. When the trigger its executed, the following error happens:
ERROR 1193 (HY000): Unknown system variable 'done'
As far as i see in the mysql cursor documentation, the 'done' variable declaration is correct. Anyone sees the problem?
The trigger:
delimiter //
CREATE TRIGGER `prestamo_positivo` AFTER UPDATE ON `prestamo`
FOR EACH ROW BEGIN
DECLARE aux VARCHAR(10);
DECLARE aux2 CHAR(10);
DECLARE c1 CURSOR FOR SELECT id_cliente FROM PRESTATARIO;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET aux=(SELECT A.id_cliente FROM PRESTATARIO A, PRESTAMO B WHERE A.numero_prestamo=OLD.numero);
IF(NEW.cantidad = 0) THEN
DELETE FROM `prestamo` WHERE numero=OLD.numero;
OPEN c1;
c1_loop: LOOP
fletch c1 into aux2;
IF done THEN LEAVE c1_loop; END IF;
IF(aux = aux2) THEN
INSERT INTO `mensaje`(mensaje, id_usuario) VALUES ("Renegociar prestamos del cliente",aux);
END IF;
END LOOP c1_loop;
CLOSE c1;
END IF;
END; //
If you check the sample code you linked in the question, you can see that done variable is explicitly declared before the continue handler, so you need to do the same. The below excerpt is from the sample code from the link you specified:
DECLARE done INT DEFAULT FALSE; //<= declare done variable here
DECLARE a CHAR(16);
DECLARE b, c INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
Also, as P.Salmon has already remarked, you cannot modify the table the trigger is declared on, therefore
DELETE FROM `prestamo` WHERE numero=OLD.numero;
line will fail with error 1442.
I have created one mysql function , this function sometimes throw lock time out exception. I want to handle this exception, here is my function
DELIMITER //
DROP FUNCTION IF EXISTS getNextNumber;
DELIMITER //
CREATE FUNCTION getNextNumber(key1 VARCHAR(20)) RETURNS INTEGER DETERMINISTIC READS SQL DATA
BEGIN
DECLARE number INTEGER;
DECLARE query_timeout INT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR 1205 SET query_timeout = TRUE;
-- Error: 1205 SQLSTATE: HY000 (ER_LOCK_WAIT_TIMEOUT)
select NUMBER into number FROM NUMBER_TABLE WHERE NUMBER_KEY = key1 FOR UPDATE;
IF query_timeout = TRUE THEN
RETURN -1;
ELSE
RETURN (number+1);
END IF;
END//
DELIMITER ;
I am using FOR UPDATE it locks that table, so if there is lock time out error then I want to return -1 else +1
I'm really struggling with this LOOP in my procedure. I can't understand what the error means. I guess anyone can just try to run this without any knowledge of the database...
DROP PROCEDURE IF EXISTS removeDuplicates;
DELIMITER $$
CREATE PROCEDURE removeDuplicates(str TEXT)
BEGIN
DECLARE temp_word TEXT;
DECLARE last_word TEXT;
DECLARE result TEXT;
DECLARE finished INT DEFAULT false;
DECLARE words_cursor CURSOR FOR
SELECT word FROM explosion;
DECLARE CONTINUE handler FOR NOT found
SET finished = true;
CALL explode(str);
DROP TABLE IF EXISTS temp_words;
CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100));
OPEN words_cursor;
loop_words: LOOP
FETCH words_cursor INTO temp_word;
IF finished THEN
LEAVE loop_words;
IF temp_word = "" THEN
SET result = CONCAT(result, temp_word, " ");
SET last_word = temp_word;
ELSEIF last_word = temp_word THEN
SET last_word = temp_word;
ELSE
INSERT INTO temp_words (t) VALUES (temp_word);
END IF;
END LOOP loop_words;
CLOSE words_cursor;
RETURN result;
END$$
DELIMITER ;
Any pointers would be gratefully received. The error I am getting is:
[ERROR in query 2] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOOP loop_words;
CLOSE words_cursor;
RETURN result;
END' at line 29
I'm sure it must be something simple, but I'll be damned if I can work it out.
Thanks, Chris
DROP PROCEDURE IF EXISTS removeDuplicates;
DELIMITER $$
CREATE PROCEDURE removeDuplicates(str TEXT , OUT OUT_STR_RESULT TEXT)
BEGIN
DECLARE temp_word TEXT;
DECLARE last_word TEXT;
DECLARE result TEXT;
DECLARE finished INT DEFAULT false;
DECLARE words_cursor CURSOR FOR
SELECT word FROM explosion;
DECLARE CONTINUE handler FOR NOT found
SET finished = true;
CALL explode(str);
DROP TABLE IF EXISTS temp_words;
CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100));
OPEN words_cursor;
loop_words: LOOP
FETCH words_cursor INTO temp_word;
IF finished THEN
LEAVE loop_words;
IF temp_word = "" THEN
SET result = CONCAT(result, temp_word, " ");
SET last_word = temp_word;
ELSEIF last_word = temp_word THEN
SET last_word = temp_word;
ELSE
INSERT INTO temp_words (t) VALUES (temp_word);
END IF;
END IF; -- i had made changes at this line.
END LOOP loop_words;
CLOSE words_cursor;
SET OUT_STR_RESULT =result;
-- RETURN result;
END$$
;
You missed one END IF.
One more thing: you can't put RETURN statement in procedure; it's only allowed in FUNCTION. Instead of that you can use OUT parameter for same.
Try above code.
I want to know How return empty resultset always from MySQL stored procedure, if there is any type error is raise on Procedure during data fetching.
Thanks
Inside your procedure, can use the ERROR HANDLER
CREATE PROCEDURE `procedure_namme`(OUT return_data TEXT)
BEGIN
DECLARE v_error_code CHAR(5);
DECLARE v_error_msg TEXT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
v_error_code = RETURNED_SQLSTATE,
v_error_msg = message_text;
SET return_data = NULL; -- IF ERROR OCCUR THEN ITS SET NULL
SELECT v_error_code,v_error_msg;
END
-- BODY WHAT YOU WANT TO WRITE(LOGIC)
END;
To know more about it you can refer this one
http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/
I can't see what is wrong with this syntax please help! I tried to look up the syntax from here
http://dev.mysql.com/doc/refman/5.5/en/declare-handler.html
DELIMITER $$
DROP PROCEDURE IF EXISTS `load_dimensions`$$
CREATE PROCEDURE `load_dimensions`( )
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE rows INT;
DECLARE result varchar(300);
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;
INSERT dimtable(col)
SELECT col FROM extract;
IF code = '00000' THEN
GET DIAGNOSTICS rows = ROW_COUNT;
SET result = CONCAT('succeeded, row count = ',rows);
INSERT INTO etl_log (result)
SELECT CONCAT('Error',state,': ',msg);
ELSE
SET result = CONCAT('failed, error = ',code,', message = ',msg);
INSERT INTO etl_log (result)
SELECT CONCAT('Error',state,': ',msg);
END IF;
END $$
From the MySQL 5.5 reference pages
The GET DIAGNOSTICS statement is not supported until MySQL 5.6.