Kalbo G Kalbo G - 6 months ago 23
MySQL Question

Stored procedure SQLWARNING exit handler not invoked

(First post. Apologize if I breach any customs or protocol.)

I want to define an exit handler for any SQLWARNING thrown in my stored procedure. But the handler is being ignored, it never fires. And I am very confused.

I am using MariaDB v. 10.0.23. However I have tested this on MariaDB v. 10.1.14 and get the same result.

Below is the SQL to create a test database.

CREATE DATABASE testerrorhandling;

USE testerrorhandling;

CREATE TABLE test
(
int_notnull INT NOT NULL
);


DELIMITER //
CREATE DEFINER=CURRENT_USER PROCEDURE create_record
(
IN p INT
)

BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION
SELECT 'Handler for SQLEXCEPTION fired.';

DECLARE EXIT HANDLER FOR SQLWARNING
SELECT 'Handler for SQLWARNING fired.';

INSERT INTO test (int_notnull) VALUES (p);

END;
//

DELIMITER ;


If I attempt to add a null value, the procedure invokes the correct handler.

MariaDB [testerrorhandling]> call create_record(null);
+---------------------------------+
| Handler for SQLEXCEPTION fired. |
+---------------------------------+
| Handler for SQLEXCEPTION fired. |
+---------------------------------+
1 row in set (0.00 sec)


But now if I attempt to add a non-integer value, a warning is thrown but the SQLWARNING error handler never fires. A value of 0 is stored in the
test
table.

MariaDB [testerrorhandling]> call create_record('this is not an integer');
Query OK, 1 row affected, 1 warning (0.04 sec)

MariaDB [testerrorhandling]> show warnings;
+---------+------+---------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'this is not an integer' for column 'p' at row 1 |
+---------+------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)


This is not what I expect or desire. I have to be doing something wrong. What am I missing here?

Answer

The warning occurs in the stored procedure call, not within the stored procedure, so the warning (within stored procedure) is not fired.

In the following example you can see that the parameter p has a value of zero (0) within the stored procedure, so there is no warning:

MariaDB [_]> DROP TABLE IF EXISTS test;
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> DROP PROCEDURE IF EXISTS create_record;
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> CREATE TABLE IF NOT EXISTS test (
    ->   int_notnull INT NOT NULL
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> DELIMITER //

MariaDB [_]> CREATE PROCEDURE create_record (
    ->   IN p INT
    -> )
    -> BEGIN
    ->     DECLARE EXIT HANDLER FOR SQLEXCEPTION
    ->         SELECT 'Handler for SQLEXCEPTION fired.';
    -> 
    ->     DECLARE EXIT HANDLER FOR SQLWARNING
    ->         SELECT 'Handler for SQLWARNING fired.';
    -> 
    ->     SELECT CONCAT('VALUE OF p: ', p);
    ->     INSERT INTO test (int_notnull) VALUES (p);
    -> END//
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> DELIMITER ;

MariaDB [_]> call create_record('this is not an integer');
+---------------------------+
| CONCAT('VALUE OF p: ', p) |
+---------------------------+
| VALUE OF p: 0             |
+---------------------------+
1 row in set (0.00 sec)

Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [_]> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------+
| Level   | Code | Message                                                                   |
+---------+------+---------------------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'this is not an integer' for column 'p' at row 1 |
+---------+------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)

In the following example, the warning is fired in the call to and within the stored procedure:

MariaDB [_]> DROP TABLE IF EXISTS test;
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> DROP PROCEDURE IF EXISTS create_record;
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> CREATE TABLE IF NOT EXISTS test (
    ->   int_notnull INT NOT NULL
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> DELIMITER //

MariaDB [_]> CREATE PROCEDURE create_record (
    ->   IN p INT
    -> )
    -> BEGIN
    ->     DECLARE EXIT HANDLER FOR SQLEXCEPTION
    ->         SELECT 'Handler for SQLEXCEPTION fired.';
    -> 
    ->     DECLARE EXIT HANDLER FOR SQLWARNING
    ->         SELECT 'Handler for SQLWARNING fired.';
    -> 
    ->     SELECT CONCAT('VALUE OF p: ', p);
    ->     SET p := 'this is not an integer';
    ->     INSERT INTO test (int_notnull) VALUES (p);
    -> END//
Query OK, 0 rows affected (0.00 sec)

MariaDB [_]> DELIMITER ;

MariaDB [_]> call create_record('this is not an integer');
+---------------------------+
| CONCAT('VALUE OF p: ', p) |
+---------------------------+
| VALUE OF p: 0             |
+---------------------------+
1 row in set (0.00 sec)

+-------------------------------+
| Handler for SQLWARNING fired. |
+-------------------------------+
| Handler for SQLWARNING fired. |
+-------------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected, 1 warning (0.00 sec)

MariaDB [_]> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------+
| Level   | Code | Message                                                                   |
+---------+------+---------------------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'this is not an integer' for column 'p' at row 1 |
+---------+------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)