MySQL PL/SQL Errors / Exceptions support
Functions like mysql_error() in PHP or try/catch blocks and MySqlException in C# are very helpful to discover problems.
Unfortunately, inside stored procedure (routine) there is no ready component to catch errors to see what would return SHOW ERRORS. But I have wanted such feature at my EVENT (Event Scheduler)! Hopefully, I realized that I can divide my code into many blocks with separate blocks responsible for error handling and thus collect these bad queries (then inspect’em all).
That can be represented in such manner:
BEGIN
DECLARE EXIT|CONTINUE HANDLER FOR SQLEXCEPTION;
BEGIN
DO SOMETHING ON ERROR;
END
DO STH;
BEGIN
DECLARE EXIT|CONTINUE HANDLER FOR SQLEXCEPTION;
BEGIN
DO SOMETHING ON ERROR2;
END
DO SOMETHING ELSE;
END
END
Example:
1. Create tables.
CREATE TABLE IF NOT EXISTS `routine_error` (
`id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Test table';
CREATE TABLE IF NOT EXISTS `routine_logs` (
`id` int(10) unsigned NOT NULL auto_increment,
`error_sql` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Test table' AUTO_INCREMENT=1 ;
2. Create procedure.
CREATE PROCEDURE `RoutineErrorTest` ()
MAIN_BLOCK: BEGIN
DECLARE MyId INT(11) UNSIGNED DEFAULT 0;
DECLARE done TINYINT DEFAULT 0;
DECLARE MyCursor CURSOR FOR Select `Id` From `routine_error`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET done = 0;
OPEN MyCursor;
REPEAT
IF done = 0 THEN
UNIQUE_JOIN_BLOCK: BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- Make clear (Rollback, etc)
/* Log. This works provided that the bug is not in this query :) */
INSERT INTO `routine_logs` (`id`, `error_sql`) VALUES (NULL, @InsertSQL);
END;
FETCH MyCursor INTO MyId;
SET @InsertSQL = CONCAT("INSERT INTO routine_error (`id`) VALUES(", MyId, ");");
PREPARE MyStmt FROM @InsertSQL;
EXECUTE MyStmt;
END UNIQUE_JOIN_BLOCK;
END IF;
UNTIL done END REPEAT;
CLOSE MyCursor;
END MAIN_BLOCK;
Voila, your errors are here:
SELECT * FROM routine_logs;
No comments yet.