`
walksing
  • 浏览: 216993 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现

阅读更多
mysql存储过程之异常处理篇
文章分类:数据库
mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现





语法如下:

DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement handler_type: CONTINUE | EXIT condition_value: SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION | mysql_error_code

Handlers类型:

1, EXIT: 发生错误时退出当前代码块(可能是子代码块或者main代码块)
2, CONTINUE: 发送错误时继续执行后续代码

condition_value:

condition_value支持标准的SQLSTATE定义;

SQLWARNING是对所有以01开头的SQLSTATE代码的速记

NOT FOUND是对所有以02开头的SQLSTATE代码的速记

SQLEXCEPTION是对所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的速记

除了SQLSTATE值,MySQL错误代码也被支持


但是对于mysql而言,优先级如下:
MySQL Error code > SQLSTATE code > 命名条件







使用SQLSTATE还是MySQL Error Code?

1,SALSTATE是标准,貌似会更portable,但是实际上MySQL、DB2、Oracle等等的存储程序语法大相径庭,所以portable的优势不存在
2,MySQL error code与SQLSTATE并不是一一对应的,比如很多MySQL error code都映射到同一SQLSTATE code(HY000)

当MySQL客户端碰到错误时,它会报告MySQL error code和相关的SQLSATE code:

mysql > CALL nosuch_sp();
ERROR 1305 (42000): PROCEDURE sqltune.nosuch_sp does not exist

具体的sqlsdate和mysql error code的对应可以在http://dev.mysql.com/doc/的MySQL reference manual的附录B找到完整的最新的error codes



condition_name:命名条件

MySQL error code或者SQLSTATE code的可读性太差,所以引入了命名条件:

语法:

Java代码
1.DECLARE condition_name CONDITION FOR condition_value  
2. 
3.condition_value:  
4.    SQLSTATE [VALUE] sqlstate_value  
5.  | mysql_error_code 
DECLARE condition_name CONDITION FOR condition_value

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code 使用:


Java代码
1.# original  
2.DECLARE CONTINUE HANDLER FOR 1216 MySQL_statements;  
3. 
4.# changed  
5.DECLARE foreign_key_error CONDITION FOR 1216;  
6.DECLARE CONTINUE HANDLER FOR foreign_key_error MySQL_statements; 
# original
DECLARE CONTINUE HANDLER FOR 1216 MySQL_statements;

# changed
DECLARE foreign_key_error CONDITION FOR 1216;
DECLARE CONTINUE HANDLER FOR foreign_key_error MySQL_statements;  用condition_name为错误代码起了个别名。



示例1:Duplicate entry Handler


Sql代码
1.CREATE PROCEDURE sp_add_location  
2.    (in_location    VARCHAR(30),  
3.     in_address1    VARCHAR(30),  
4.     in_address2    VARCHAR(30),  
5.     zipcode        VARCHAR(10),  
6.     OUT out_status VARCHAR(30))  
7.BEGIN 
8.    DECLARE CONTINUE HANDLER  
9.        FOR 1062  
10.        SET out_status='Duplicate Entry';  
11. 
12.    SET out_status='OK';  
13.    INSERT INTO locations  
14.        (location,address1,address2,zipcode)  
15.    VALUES 
16.        (in_location,in_address1,in_address2,zipcode);  
17.END; 
CREATE PROCEDURE sp_add_location
    (in_location    VARCHAR(30),
     in_address1    VARCHAR(30),
     in_address2    VARCHAR(30),
     zipcode        VARCHAR(10),
     OUT out_status VARCHAR(30))
BEGIN
    DECLARE CONTINUE HANDLER
        FOR 1062
        SET out_status='Duplicate Entry';

    SET out_status='OK';
    INSERT INTO locations
        (location,address1,address2,zipcode)
    VALUES
        (in_location,in_address1,in_address2,zipcode);
END;


示例2: Last Row Handler




Sql代码
1.CREATE PROCEDURE sp_not_found()  
2.    READS SQL DATA  
3.BEGIN 
4.    DECLARE l_last_row INT DEFAULT 0;  
5.    DECLARE l_dept_id INT:  
6.    DECLARE c_dept CURSOR FOR 
7.        SELECT department_id FROM departments;  
8.    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row=1;  
9. 
10.    OPEN c_dept;  
11.    dept_cursor: LOOP  
12.        FETCH c_dept INTO l_dept_id;  
13.        IF (l_last_row=1) THEN 
14.            LEAVE dept_cursor;  
15.        END IF;  
16.    END LOOP dept_cursor;  
17.    CLOSE c_dept;  
18.END; 
CREATE PROCEDURE sp_not_found()
    READS SQL DATA
BEGIN
    DECLARE l_last_row INT DEFAULT 0;
    DECLARE l_dept_id INT:
    DECLARE c_dept CURSOR FOR
        SELECT department_id FROM departments;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row=1;

    OPEN c_dept;
    dept_cursor: LOOP
        FETCH c_dept INTO l_dept_id;
        IF (l_last_row=1) THEN
            LEAVE dept_cursor;
        END IF;
    END LOOP dept_cursor;
    CLOSE c_dept;
END;


综合示例:

Sql代码
1.CREATE PROCEDURE sp_add_department  
2.    (p_department_name     VARCHAR(30),  
3.     p_manager_surname     VARCHAR(30),  
4.     p_manager_firstname   VARCHAR(30),  
5.     p_location            VARCHAR(30),  
6.     OUT p_sqlcode         INT,  
7.     OUT p_status_message  VARCHAR(100))  
8.BEGIN 
9. 
10.    /* START Declare Conditions */  
11. 
12.    DECLARE duplicate_key CONDITION FOR 1062;  
13.    DECLARE foreign_key_violated CONDITION FOR 1216;  
14. 
15.    /* END Declare COnditions */  
16. 
17.    /* START Declare variables and cursors */  
18. 
19.    DECLARE l_manager_id INT;  
20.    DECLARE csr_mgr_id CURSOR FOR 
21.        SELECT employee_id FROM employees  
22.        WHERE surname=UPPER(p_manager_surname)  
23.        AND firstname=UPPER(p_manager_firstname);  
24. 
25.    /* END Declare variables and cursors */  
26. 
27.    /* START Declare Exception Handlers */  
28. 
29.    DECLARE CONTINUE HANDLER FOR duplicate_key  
30.    BEGIN 
31.        SET p_sqlcode=1052;  
32.        SET p_status_message='Duplicate key error';  
33.    END;  
34. 
35.    DECLARE CONTINUE HANDLER FOR foreign_key_violated  
36.    BEGIN 
37.        SET p_sqlcode=1216;  
38.        SET p_status_message='Foreign key violated';  
39.    END;  
40. 
41.    DECLARE CONTINUE HANDLER FOR NOT FOUND  
42.    BEGIN 
43.        SET p_sqlcode=1329;  
44.        SET p_status_message='No record found';  
45.    END;  
46. 
47.    /* END Declare Exception Handlers */  
48. 
49.    /* START Execution */  
50. 
51.    SET p_sqlcode=0;  
52.    OPEN csr_mgr_id;  
53.    FETCH csr_mgr_id INTO l_manager_id;  
54. 
55.    IF p_sqlcode<>0 THEN     /* Failed to get manager id */  
56.        SET p_status_message=CONCAT(p_status_message,' when fetching manager id');  
57.    ELSE                     /* Got manager id, we can try and insert */  
58.        INSERT INTO departments (department_name, manager_id, location)  
59.        VALUES(UPPER(p_department_name), l_manager_id, UPPER(p_location));  
60.        IF p_sqlcode<>0 THEN /* Failed to insert new department */  
61.            SET p_status_message=CONCAT(p_status_message, ' when inserting new department');  
62.        END IF;  
63.    END IF;  
64. 
65.    CLOSE csr_mgr_id;  
66. 
67.    /* END Execution */  
68. 
69.END  
分享到:
评论

相关推荐

    MySQL存储过程的异常处理方法

    本实例展示了如何在MySQL存储过程中实现异常处理,以捕获并处理可能出现的错误。 首先,我们注意到在创建存储过程`myProc`时,使用了`delimiter $$`来改变MySQL客户端的语句分隔符,这是为了在存储过程中使用多个...

    MySQL定义异常和异常处理详解

    在MySQL中,异常定义和处理主要是通过`DECLARE`语句来实现的。 1. **异常定义** 异常定义是创建一个特定的条件(condition),这个条件关联到可能发生的错误或警告。语法如下: ```sql DECLARE condition_name ...

    [MySQL] 存储过程错误异常处理例子

    总结来说,`DECLARE EXIT HANDLER FOR SQLEXCEPTION`是MySQL存储过程中处理错误和异常的关键工具。它使得我们能够优雅地处理可能出现的问题,确保即使在异常情况下,程序也能按照预定的方式进行操作,从而提升整个...

    MySQL存储过程 ERROR Handler 异常处理.doc

    MySQL存储过程中的ERROR Handler是用于异常处理的关键机制,它允许开发者在遇到错误时进行定制化的响应,而不是让整个过程崩溃。在存储过程中,错误处理通常涉及声明一个或多个HANDLER,这些HANDLER会在特定错误发生...

    MySQL存储过程中一些基本的异常处理教程

    Mysql 支持异常处理,通过定义 CONTINUE/EXIT 异常处理的 HANDLER 来捕获 SQLWARNING/NOT FOUND/SQLEXCEPTION (警告 / 无数据 / 其他异常)。其中, FOR 后面可以改为 SQLWARNING, NOT FOUND, SQLEXCEPTION 来指示...

    MySQL存储过程系统学习资料

    MySQL存储过程是数据库管理系统中的一个重要概念,它是一组为了完成特定功能的SQL语句集,经编译后存储在MySQL服务器中,用户可以调用这个预编译的语句集来执行任务,而不是每次需要时都重新编写相同的SQL代码。...

    MySQL存储过程.pdf

    MySQL存储过程是数据库管理系统中的一种重要功能,它允许开发者预编译一组SQL语句并封装成一个可重复使用的对象。这种技术在处理复杂的业务逻辑、提高数据操作效率以及减少网络传输时非常有用。本文件“MySQL存储...

    MySQL实验报告5(存储过程与函数)(1)(1).pdf

    根据提供的文件内容,本篇实验报告主要围绕MySQL数据库中存储过程和函数的应用,涵盖了创建存储过程、函数、游标以及异常处理等高级特性。下面将详细解析报告中的每个知识点。 1. 创建存储过程 存储过程是一种在...

    Mysql5存储过程中文详解

    从给定的文件信息来看,文章主要探讨的是MySQL5.0版本中新引入的存储过程功能。存储过程在数据库管理系统中扮演着重要的角色,它允许开发者编写可重用的代码块,这些代码块可以执行一系列复杂的数据库操作。在MySQL...

    精通MySQL存储过程和函数

    本手册适用于对MySQL存储过程和函数感兴趣的开发者和技术人员,特别是那些希望深入了解并掌握如何在实际项目中高效利用这些功能的专业人士。手册中的所有示例和操作均基于CentOS 6.2 64位系统和MySQL 5.6版本进行。 ...

    MySQL5新特性之存储过程MySQL5新特性之存储过程

    4. **异常处理**:通过`DECLARE`、`BEGIN...END`和`HANDLER`语句,MySQL5提供了错误处理机制,可以在存储过程中捕获并处理异常,增强了程序的健壮性。 5. **动态SQL**:MySQL5支持在存储过程中执行动态生成的SQL...

    \MySQL 5.0 存储过程.pdf

    4. **错误处理**:通过 `DECLARE CONTINUE HANDLER` 可以处理存储过程中出现的异常情况。 5. **游标支持**:可以使用游标来逐行处理查询结果,这对于需要逐行处理大量数据的情况非常有用。 6. **安全特性**:提供了...

    mysql5.0官方存储过程翻译

    MySQL存储过程是数据库管理系统中的一个重要组成部分,特别是在MySQL 5.0版本中,它提供了一种组织和执行复杂SQL语句的高效方式。本资料集合包含了对MySQL 5.0官方存储过程的详细翻译,旨在帮助学习者深入理解并熟练...

    mysql存储过程中的异常处理解析

    在MySQL中,异常处理主要是通过声明和使用HANDLER来实现的。以下是对这一主题的详细解释: 1. **异常处理定义**: 在MySQL的存储过程中,你可以定义一个或多个HANDLER来捕获特定的异常或错误情况。HANDLER由`...

Global site tag (gtag.js) - Google Analytics