What happens when a exception occurs in exception block - exception

suppose in my procedure, error occurred and it went to exception block.
while entering the logs for error occurred another error takes placein exception block itself.
What happens then ...

The easiest way to find out is surely to try it?
declare
dummy integer;
begin
select 99 into dummy from all_objects; -- Will raise TOO_MANY_ROWS
exception
when too_many_rows then
select 77 into dummy from dual where 2=3; -- Will raise NO_DATA_FOUND
end;
/
When you run that you will get:
ORA-01403: no data found
ORA-06512: at line 8

Related

Raise Exception issue in big query scripting

I would like to print the custom message as an exception error with the RAISE keyword in big query script.
But, the below command lines is throwing an error at the raise command. But, if I remove the raise command it is working fine.
Could you please help me how I have to raise a custom error message??
Also, to know more about the RAISE [USING MESSAGE = message];.
BEGIN
SELECT 1/0; -- attempts to divide by zero
RAISE USING message = "divisible with zero is not allowed.";
EXCEPTION WHEN ERROR THEN
SELECT FORMAT("Hey, you. When you executed %s at %s, it caused an error: %s. Please don't do that.", ##error.statement_text, ##error.formatted_stack_trace, ##error.message);
END;
The RAISE statement must only be used within an EXCEPTION clause. The RAISE statement will re-raise the exception that was caught, and preserve the original stack trace.
Ref: https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting#raise
So if you want to raise an exception with custom message, it should be:
BEGIN
SELECT 1/0; -- attempts to divide by zero
EXCEPTION WHEN ERROR THEN
RAISE USING message = FORMAT("Hey, you. When you executed %s at %s, it caused an error: %s. Please don't do that.", ##error.statement_text, ##error.formatted_stack_trace, ##error.message);
END;

No data found not executing in trigger

The below portion is the relevant part of my trigger
BEGIN SELECT rec_date
INTO lv_rec_date
FROM receipts_table
WHERE receipts_number = new.receipts_number
EXCEPTION WHEN NO_DATA_FOUND THEN
lv_partial := FALSE;
END;
The problem is that when it executes this portion, instead of capturing it nicely, I get the following error
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "APP.BEF_ROW_TRIGGER", line 66
ORA-04088: error during execution of trigger 'APP.BEF_ROW_TRIGGER'
This worked fine in Oracle 10 and below. I checked and line 66 in the USER_SOURCE for this trigger is exactly the EXCEPTION WHEN NO_DATA_FOUND THEN line. It seems to be hitting the NO_DATA_FOUND error, but the error catching doesn't seem to be working.
Are there any changes in Oracle 11g that I should be aware of?
Never mind, false alarm ^_^. The error was on line 66 of a procedure being called AFTER this section, but the error message was showing it was from the trigger. Ouch.....
Sorry for the trouble

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.

MySQL exception handler access exception being handled

I'm trying to rollback on an error, but still let the client receive the error. This might actually be impossible, unless there is a way to access the error in an exception handler.
It's possible to "throw" from an exception, i.e. it's possible to raise a signal:
CREATE PROCEDURE p ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SIGNAL SQLSTATE VALUE '99999'
SET MESSAGE_TEXT = 'An error occurred';
END;
DROP TABLE no_such_table;
END;
But this sample code from the MySQL doc looks horrible, because it literally swallows all errors and jams them into one.
SHOW ERRORS seems relevant, but I don't see any way to work with it programmatically, e.g. SELECT Code FROM (SHOW ERRORS); is not possible.
Is this possible? Is there a better practice that I'm missing entirely?
Looks like RESIGNAL is what you are looking for.
RESIGNAL makes it possible to both handle an error and return the error information. Otherwise, by executing an SQL statement within the handler, information that caused the handler's activation is destroyed. RESIGNAL also can make some procedures shorter if a given handler can handle part of a situation, then pass the condition “up the line” to another handler.
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`resig` $$
CREATE PROCEDURE `test`.`resig` ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT 'I executed something before throwing the error' as `this_works`;
RESIGNAL;
END;
SELECT foo FROM bar WHERE baz = 0;
END $$
DELIMITER ;
mysql> call resig();
+------------------------------------------------+
| this_works |
+------------------------------------------------+
| I executed something before throwing the error |
+------------------------------------------------+
1 row in set (0.00 sec)
ERROR 1054 (42S22): Unknown column 'foo' in 'field list'
mysql>

How to catch and re-throw all errors in MySQL

I can't seem to find anywhere how to catch and re-throw any errors or warnings that can occur in a procedure.
What I want is the syntax to do the following:
create procedure myProcedure()
begin
declare exit handler for ANYTHING_WRONG_THAT_CAN_BE_CAUGHT_WARNINGS_INCLUDED
begin
rollback;
RE_THROW THE_THING_THAT_WAS_CAUGHT;
end;
start transaction;
-- do some stuff
commit;
end; //
The reason being that I want to force a rollback on an error or warning but leave it up to the client to decide what to do with the specific error.
The all-cap areas are the portions where I do not know what to put.
Thanks for any help!
Edit -------
I have since learned it is not possible to do what I have asked :'(.
Instead I have a single error for anything that goes wrong and used the following code:
declare exit handler for sqlwarning, sqlexception begin
rollback;
call error();
end;
(error() does not exist)
To catch all SQL exceptions, use:
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SQLWARNINGS can be used to catch warnings also.
Inside the exception handler, to raise the error or warning that was just caught, use:
RESIGNAL
See the documentation for the RESIGNAL statement:
http://dev.mysql.com/doc/refman/5.5/en/resignal.html
This is available since MySQL 5.5