Return Exception from MySQL stored procedure - mysql

I am using following Exception handler in my stored procedure.
DECLARE EXIT HANDLER FOR SQLEXCEPTION
Begin
DROP TABLE temp_checkForDuplicate;
SET outDone = -1;
End;
Here I found some code for particular
exception '1062'
DECLARE EXIT handler for 1062 set o_error_status := "Duplicate entry in table";
What if I don't know the exception number: How to handle any exception and throw its number and its message?

In versions of MySQL prior to 5.5 you cannot really do this.
Version 5.5 has introduced Signals which provide a mechanism to return specific error codes or conditions.
http://dev.mysql.com/doc/refman/5.5/en/signal.html
Version 5.6 has added "Get Diagnostics" which provides the information you need.
http://dev.mysql.com/doc/refman/5.6/en/get-diagnostics.html
You can also find related information in these SO Questions.
MySQL Stored Procedure Error Handling
How to raise an error within a MySQL function

Related

How to read exception details in MYSQL Diagnostic area

I am using Mysql 5.7.14. The get diagnostics statement showing error though i am using 5.7. Sample lines what i am using are something like below where i need to extract error information but unfortunately it couldn't. please help me.
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;#I HAVE TO ROOL BACK A TRASACTION WHEN EVER AN EXCEPTION OCCURS.
GET DIAGNOSTICS CONDITION 1 ERRORSTATE=RETURNED_SQLSTATE,
ERRORNUMBER=MYSQL_ERRNO, ERRORTEXT=MESSAGE_TEXT;
END;

Is there a way to get the line of MySQL code that caused a SQLEXCEPTION in my stored procedure?

I use this code in my stored procedure to get info on a SQLEXCEPTION:
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS condition 1
#SQLState = RETURNED_SQLSTATE, #SQLMessage = MESSAGE_TEXT;
SELECT CONCAT('Database error occurred, state - ',#SQLState, '; error msg - ', #SQLMessage) INTO #errorString;
CALL Collectors_Errors
(#errorString,
'Collectors_UpdateGame',
barcodeApp,
usernameApp);
END;
The problem with this code is even though I know what the error is, it doesn't tell me at which line it occurred. And some of my sprocs are very long.
Is there a way to determine which line number, or what the line was, that caused the exception?
You can try the rdebug tool for debugging your stored procedures. I have not used it, but I find the rest of the tools in common_schema to be super helpful.
There may be an easier quick fix for finding exactly where this one error comes from, but in you are working with long stored procedures you may find rdebug to be helpful beyond this one error.

Logging with MYSQL Handlers

I'm hoping this isn't just duplicating this question.
I have read the documentation but I don't think I fully understand how to use this properly yet.
I would like to catch errors thrown in my stored procedures and log those errors in a table. This is mostly for experimental purposes. I am wondering is there a way to catch any error and then log the code and error to a table.
So far it looks like I have to declare a different handler for each error. Is this correct or is there a way to catch all errors and get the code and message.
For example in each stored procedure I'm declaring a couple of handlers
DECLARE EXIT HANDLER FOR 1062
BEGIN
SELECT 'Attempt to create a duplicate entry occurred';
END;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'Unexpected Error Ocurred';
END;
Instead of
SELECT 'custom message';
I want to do
INSERT INTO errorLogs(code, message);
Is this possible without declaring a load of handlers and adding each code manually?
Really appreciate any help pointing me in the right direction.
It looks like this is not really possible until I can use an updated version of MYSQL with DIAGNOSTICS. I found this question which is basically the same as mine. Ah well.

MySQL Stored Procedure Error Handling

I believe there is nothing currently available in MySQL that allows access to the SQLSTATE of the last executed statement within a MySQL stored procedure. This means that when a generic SQLException is raised within a stored procedure it is hard/impossible to derive the exact nature of the error.
Does anybody have a workaround for deriving the SQLSTATE of an error in a MySQL stored procedure that does not involve declaring a handler for every possible SQLSTATE?
For example - imagine that I am trying to return an error_status that goes beyond the generic "SQLException happened somewhere in this BEGIN....END block" in the following:
DELIMITER $$
CREATE PROCEDURE `myProcedure`(OUT o_error_status varchar(50))
MY_BLOCK: BEGIN
DECLARE EXIT handler for 1062 set o_error_status := "Duplicate entry in table";
DECLARE EXIT handler for 1048 set o_error_status := "Trying to populate a non-null column with null value";
-- declare handlers ad nauseum here....
DECLARE EXIT handler for sqlexception set o_error_status:= "Generic SQLException. You'll just have to figure out the SQLSTATE yourself...." ;
-- Procedure logic that might error to follow here...
END MY_BLOCK$$
Any tips?
PS I am running MySQL 5.1.49
I believe there is nothing currently available in MySQL that allows access to the SQLSTATE of the last executed statement within a MySQL stored procedure. This means that ... it is hard/impossible to derive the exact nature of the error.
Luckily that is not true.
SHOW ERRORS LIMIT 1 -- for SQL-state > 2
SHOW WARNINGS LIMIT 1 -- for SQL-state 1,2
Will show the last error or warning.
In order to prevent listing each and every error, you can handle a class of SQL-errors like so:
SQLWARNING is shorthand for the class of SQLSTATE values that begin with '01'.
NOT FOUND is shorthand for the class of SQLSTATE values that begin with '02'. This is relevant only within the context of cursors and is used to control what happens when a cursor reaches the end of a data set. If no more rows are available, a No Data condition occurs with SQLSTATE value 02000. To detect this condition, you can set up a handler for it (or for a NOT FOUND condition). An example is shown in Section 12.7.5, “Cursors”. This condition also occurs for SELECT ... INTO var_list statements that retrieve no rows.
SQLEXCEPTION is shorthand for the class of SQLSTATE values that do not begin with '00', '01', or '02'.
So to handle an exception, you need to only do:
DECLARE EXIT HANDLER FOR SQLSTATE SQLEXCEPTION .....;
Links:
http://dev.mysql.com/doc/refman/5.5/en/signal.html
http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
GET DIAGNOSTICS is available in 5.6.4
See
http://dev.mysql.com/doc/refman/5.6/en/get-diagnostics.html
I am doing the following workaround: using a SELECT to provocate an error. For example:
SELECT RAISE_ERROR_unable_to_update_basket;
This will result in the following error message (example):
ERROR 1054 (42S22): Unknown column 'RAISE_ERROR_unable_to_update_basket' in 'field list'
I am wrapping my call to a stored procedure in a try { ... } catch { ... } and now can handle this error. This will of course only work for provocating custom error messages from inside your stored procedure and will not handle any SQL or database errors, that might occur (because of duplicate-key entry). In the latter case, you might be able to workaround this using the solution of Johan.

How to catch any exception in triggers and store procedures for mysql?

I have been trying to catch mysql exception especially for triggers and store procedures.How can we catch the exception from mysql side?. I still not found any solution. your help would be appreciate.
Thanks
Hitesh
Because this comes up in the top of my search for MySQL error handling in triggers, I thought I'd share my solution for MySQL 5.5+
My original post: https://stackoverflow.com/a/26115231/1733365 Duplicated below...
Because this article comes up towards the top when I search for error handling in MySQL triggers, I thought I'd share some knowledge.
If there is an error, you can force MySQL to use a SIGNAL, but if you don't specify it as a class as SQLEXCEPTION, then nothing will happen, as not all SQLSTATEs are considered bad, and even then you'd have to make sure to RESIGNAL if you have any nested BEGIN/END blocks.
Alternatively, and probably simpler still, within your trigger, declare an exit handler and resignal the exception.
CREATE TRIGGER `my_table_AINS` AFTER INSERT ON `my_table` FOR EACH ROW
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
RESIGNAL;
DECLARE EXIT HANDLER FOR SQLWARNING
RESIGNAL;
DECLARE EXIT HANDLER FOR NOT FOUND
RESIGNAL;
-- Do the work of the trigger.
END
And if in your body there occurs an error, it will be thrown back up to the top and exit with an error. This can also be used in stored procedures and whatnot.
This works with anything version 5.5+.
Check out the syntax for DECLARE HANDLER
http://dev.mysql.com/doc/refman/5.1/en/declare-handler.html
Also, if you're trying to debug a SP, this might be helpful for you:
http://www.bluegecko.net/mysql/debugging-stored-procedures/