存储过程未调用SQLWARNING退出处理程序

时间:2016-06-08 07:32:34

标签: mysql sql stored-procedures mariadb

(第一篇文章。如果我违反任何习俗或协议,请道歉。)

我想为我的存储过程中抛出的任何SQLWARNING定义一个退出处理程序。但处理程序被忽略,它永远不会触发。而且我很困惑。

我正在使用MariaDB v.10.0.23。但是我已经在MariaDB v.1.1.14上测试了这个并得到了相同的结果。

以下是创建测试数据库的SQL。

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 ;

如果我尝试添加空值,则该过程将调用正确的处理程序。

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

但是现在如果我尝试添加非整数值,则会抛出警告,但SQLWARNING错误处理程序永远不会触发。值0存储在test表中。

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)

这不是我所期望或渴望的。我必须做错事。我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

警告发生在存储过程调用中,而不是存储过程中,因此不会触发警告(在存储过程中)。

在以下示例中,您可以看到参数p在存储过程中的值为零(0),因此没有警告:

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)

在以下示例中,在对存储过程的调用和内部过程中触发警告:

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)