Exception using TRY CATCH in mysql stored procedure - mysql

Following is the procedure in which i am trying to catch the exception, if there is any in stored procedure
DROP PROCEDURE IF EXISTS test;
DELIMITER //
CREATE PROCEDURE test( IN contextFilter TEXT)
BEGIN TRY
set #sub_query = 'SELECT id from test_table';
PREPARE stmt_query FROM #sub_query;
SELECT #sub_query;
EXECUTE stmt_query;
DEALLOCATE PREPARE stmt_query;
END TRY //
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
DELIMITER ;
When i try to source the stored procedure , i am getting the following exception
source /home/test.sql;
Query OK, 0 rows affected (0.01 sec)
ERROR 1064 (42000) at line 5 in file: '/home/test.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'set #sub_query = 'SELECT id from test_table';
PREPARE stmt_query FROM #' at line 5
ERROR 1064 (42000) at line 17 in file: '/home/test.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CATCH
SELECT ERROR_NUMBER() AS ErrorNumber,ERROR_MESSAGE() AS ErrorMessage;
' at line 1

The post above helped me, but I still had to do some research on my own. In order to provide a complete example you can see below. This code will declare a handler for "catching" SQLExceptions and then exit if it occurs.
DROP PROCEDURE IF EXISTS `SP_TEST`;
DELIMITER //
CREATE PROCEDURE `SP_TEST`()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 #p1 = RETURNED_SQLSTATE, #p2 = MESSAGE_TEXT;
SELECT CONCAT(#p1, ':', #p2);
END;
SELECT FAKE_COLUMN FROM MY_TABLE;
END //
CALL SP_TEST;
This works in mySQL version 5.7 and hope it helps you.

In mySql, there is no try... catch block like in Java. You can I handle errors through error handling?
Syntax
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement
handler_action:
CONTINUE
| EXIT
| UNDO
condition_value:
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
The handler_action value indicates what action the handler takes after execution of the handler statement:
CONTINUE: Execution of the current program continues.
EXIT: Execution terminates for the BEGIN ... END compound statement in which the handler is declared. This is true even if the condition occurs in an inner block.
UNDO: Not supported.
For more info go to Official site

Related

Mariadb 10.3.29 BEGIN... END statement not working with DECLARE

i am having an issue getting the following statement to run in Mariadb 10.3.29 and 10.3.13
delimiter |
BEGIN NOT ATOMIC
DECLARE finished int default 0;
DECLARE query varchar(500) default "";
DECLARE curQuery
CURSOR FOR
SELECT CONCAT('ALTER TABLE ',TABLE_SCHEMA ,'.', table_name, ' MODIFY COLUMN `type` tinyint(1) DEFAULT NULL NULL COMMENT "test";')
FROM information_schema.tables WHERE table_name = 'test_table';
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
open curQuery;
executeQuery: LOOP
FETCH curQuery INTO query;
IF finished = 1 THEN
LEAVE executeQuery;
END IF;
prepare stmt from query;
execute stmt;
END LOOP executeQuery;
CLOSE curQuery;
END|
I am getting the following error:
Reason:
SQL Error [1064] [42000]: (conn=54) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DECLARE finished int default 0;
Using dbeaver 21.3.3
According to these docs here: https://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/ i should be able to do this outside of a "stored program" on mariadb 10.1.1+. However, i can get this to run inside of a stored procedure, but i would really like to run this in plain SQL if possible.
Thanks in advance.
You appear to need BEGIN NOT ATOMIC explicitly, which is what the examples show.
fiddle
https://mariadb.com/kb/en/begin-end/:
NOT ATOMIC is required when used outside of a stored procedure. Inside stored procedures or within an anonymous block, BEGIN alone starts a new anonymous block.

How to call procedure inside cursor in MariaDB

I'm new to MariaDB, I only have some experience in MS SQL Server.
I'm trying to call a procedure for every row returned from a query.
But I can't find the error when trying to create a procedure with a cursor.
I'm using Heidy to connect to MariaDB 10.0
CREATE PROCEDURE SetAll()
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE id INT ;
DECLARE cur CURSOR FOR SELECT aID FROM Customers ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
OPEN cur;
testLoop: LOOP
FETCH cur INTO id;
IF done THEN
LEAVE testLoop;
END IF;
CALL SetById(id);
END LOOP testLoop;
CLOSE cur;
END
Error: "/* Error de SQL (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 4 */"
My precedure SetById(id) work just fine.

Syntax error when calling stored procedure inside stored procedure

I'm trying to call a stored procedure inside another stored procedure.
I'm getting a syntax error in the statement where main procedure calls the child procedure.
here is my query
DROP PROCEDURE GetAllProducts;
DELIMITER //
CREATE PROCEDURE GetAllProducts()
BEGIN
DECLARE finished INT DEFAULT 0;
DECLARE myName varchar(60);
DEClARE myCursor CURSOR FOR
SELECT Name FROM Test;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished =1 ;
OPEN myCursor;
get_email: LOOP
FETCH myCursor INTO myName;
IF finished = 1 THEN
LEAVE get_email;
END IF;
-- Line which shows a syntax error
EXEC UpdateProdcut myName;
END LOOP get_email;
CLOSE myCursor;
DEALLOCATE myCursor;
END //
DELIMITER ;
This is the error message
ERROR 1064 (42000): 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 'UpdateProdcut myName OUTPUT;
mysql version is 5.5.54
any idea about this ?
Thanks.
Use CALL instead:
call UpdateProdcut(myName);
execute is used for prepared statements.
Ref:
https://dev.mysql.com/doc/refman/5.5/en/call.html

Mysql error 1064 in Mysql 5.1- unable execute successfully

I am trying to write trigger in Mysql (5.1), but getting following error, please help.
The error is:
SQL Error (1064): 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 '' at line 5.
Purpose for writing trigger:
I am writing application where I am assigning users, and I want to store unassigned usercount to field cluster_count in IX_branchdetails table.After updating the base table.
trigger:
DELIMITER $$
CREATE TRIGGER upd_trg AFTER
UPDATE ON DBNAME.BASETABLE
FOR EACH ROW
BEGIN
DECLARE m_branchcode INTEGER;
DECLARE cnt INTEGER;
DECLARE cursor_branch CURSOR FOR
SELECT DISTINCT branchcode
FROM ix_branchdetails;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open cursor_branch;
my_loop: loop
set done = false;
fetch cursor_branch into m_branchcode;
if done then
leave my_loop;
end if;
select count(1) into cnt from (select count(1) from BASETABLE Where IX_BRANCHCODE = m_branchcode) as temp;
update DBANAME.ix_branchdetails set DBANAME.ix_branchdetails.cluster_count = cnt where DBANAME.ix_branchdetails.BRANCHCODE = m_branchcode;
end loop my_loop;
close cursor_branch;
END $$
DELIMITER ;
I don't see a declare for the done variable:
DECLARE done TINYINT DEFAULT FALSE;
The semicolon (;) is the default delimiter for MySQL statements. To get a procedure/function/trigger defined, we normally see the statement delimiter changed to a string that doesn't appear in the statement:
DELIMITER $$
CREATE PROCEDURE ...
END$$
DELIMITER ;
If the delimiter is not changed from the semicolon, then when MySQL encounters the first semicolon in your procedure/function/trigger, it sees that as the end of the statement, which is not what you want. You want MySQL to see the entire block of code as a single statement.

mysql transaction error handling

DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN
ROLLBACK;
END;
START TRANSACTION;
UPDATE tbl_order SET TransactionID="abc" WHERE OrderID=1;
UPDATE tbl_order SET TransactionID="xyz" WHERE OrderID=;
UPDATE tbl_order SET TransactionID="zzz" WHERE OrderID=13;
COMMIT;
for some reason order 1 and 13 are filled without rollback and i get syntax error for the exit hadler.
Query: DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN ROLLBACK
Error Code: 1064
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 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN
ROLLBACK' at line 1
can someone help me figure out what i'm doing wrong?
Thanks in advance
EDIT
UPDATE tbl_order SET TransactionID="xyz" WHERE OrderID=;
is intentional
I believe exit handlers can only be used in stored procedures. The documentation doesn't explicitly state this, but alludes to
Conditions may arise during stored program execution that require special handling
http://dev.mysql.com/doc/refman/5.1/en/condition-handling.html
I know this is quite outdated topic, but I encountered the same error when declaring my own procedure with transaction and error handling. The above procedure looks well, something OP didn't copy as it seems. The order is important and it should look like this:
Procedure declaration
Declaration of variables
ERROR HANDLING
Start transaction
Statements
Commit
End
In my case, it looks like this:
DELIMITER //
CREATE PROCEDURE pAddUser(IN _nick VARCHAR(30))
BEGIN
DECLARE doesUserExist BOOLEAN;
DECLARE accountCreationDate DATE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
SET doesUserExist = (SELECT EXISTS(SELECT * FROM tblUser WHERE nick=_nick));
IF NOT doesUserExist THEN
SET accountCreationDate = CURDATE();
INSERT INTO tblUser (nick, accountCreation) VALUES (_nick, CURDATE());
ELSE
SELECT CONCAT("Nick '", _nick, "' is in use!") AS 'Console output';
END IF;
COMMIT;
END;
//
DELIMITER ;