mysql存储过程中的异常处理

定义异常捕获类型及处理方法:

    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  

这里面需要注意几点:

a、condition_value [,condition_value],这个的话说明可以包括多种情况(方括弧表示可选的),也就是一个handler可以定义成针对多种情况进行相应的 操作;另外condition_value可以包括的值有上面列出来的6种:

1、mysql_error_code,这个表示mysql的错误代码,错误代码是一个数字,完成是由mysql自己定义的,这个值可以参考mysql数据库错误代码及信息。
2、SQLSTATE [VALUE] sqlstate_value,这个同错误代码类似形成一一对应的关系,它是一个5个字符组成的字符串,关键的地方是它从ANSI SQL和ODBC这些标准中引用过来的,因此更加标准化,而不像上面的error_code完全是mysql自己定义给自己用的,这个和第一个类似也可以 参考mysql数据库错误代码及信息。
3、condtion_name,这个是条件名称,它使用DECLARE...CONDITION语句来定义,这个后面我们会介绍如何定义自己的condition_name。
4、SQLWARNING,表示SQLTATE中的字符串以‘01’起始的那些错误,比如Error: 1311 SQLSTATE: 01000 (ER_SP_UNINIT_VAR)
5、NOT FOUND,表示SQLTATE中的字符串以‘02’起始的那些错误,比如Error: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)
6、SQLEXCEPTION,表示SQLSTATE中的字符串不是以'00'、'01'、'02' 起始的那些错误,这里'00'起始的SQLSTATE其实表示的是成功执行而不是错误,另外两个就是上面的4和5的两种情况。

上面的6种情况其实可以分为两类:

一类就是比较明确的处理,就是对指定的错误情况进行处理,包括1、2、3这三种方式;

另一类是对对应类型的错误的 处理,就是对某一群错误的处理,包括4、5、6这三种方式。这个是介绍了condition_value。另外还要注意的一个内容是MySQL在默认情况 下(也就是我们没有定义处理错误的方法-handler)自己的错误处理机制:1、对于SQLWARNING和NOT FOUND的处理方法就是无视错误继续执行,所以在游标的例子里面如果我们没有对repeat的条件判断的那个值做个no_more_products=1的handler来处理,那么循环就会一直下去。2、对于SQLEXCEPTION的话,其默认的处理方法是在出现错误的地方就终止掉了。

b、statement,这个比较简单就是当出现某种条件/错误时,我们要执行的语句,可以是简单的如 SET  var = value这样的简单的语句,也可以是复杂的多行的语句,多行的话可以使用BEGIN  .....  END这里把语句包括在里面(这个好比delphi里面的情况,注意到我们的存储过程也是多行的,所以也要BEGIN .... END)。
c、handler_action,这个表示当执行完上面的statement后,希望执行怎样的动作,这里包括CONTINUE、EXIT、UNDO, 表示继续、退出、撤销(暂时不支持)。这边就是两种动作,其实这两种动作在上面也说过了,CONTINUE就是一个是SQLWARNING和NOT FOUND的默认处理方法,而EXIT就是SQLEXCEPTION的默认处理方法。

另:

condition_name:命名条件

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

语法:

DECLARE condition_name CONDITION FOR condition_value  
 
condition_value:  
    SQLSTATE [VALUE] sqlstate_value  
  | mysql_error_code  

使用:

# 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;  

示例:

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; 

MySQL 存储过程 常用语法

存储过程P_GET_CLASS_NAME是根据输入的班级号判断班级名称

存储过程P_INSERT_STUDENT是接收输入的学生信息,最终将信息插入学生表。

    DROP PROCEDURE IF EXISTS `P_GET_CLASS_NAME`;  
    CREATE PROCEDURE P_GET_CLASS_NAME(IN ID int,OUT NAME VARCHAR(50))  
    BEGIN  
        IF(ID = 1) THEN   
              SET NAME = '一班';  
        END IF;  
        IF(ID = 2) THEN   
              SET NAME = '二班';  
        END IF;  
    END;  
      
      
    DROP PROCEDURE IF EXISTS `P_INSERT_STUDENT`;  
    CREATE PROCEDURE P_INSERT_STUDENT(IN ID INT,IN NAME VARCHAR(10),IN CLASSNO INT,IN BIRTH DATETIME)  
    BEGIN  
         SET @ID = ID;  
         SET @NAME = NAME;  
         SET @CLASSNO = CLASSNO;  
         SET @BIRTH = BIRTH;  
         SET @CLASSNAME = NULL;  
         CALL P_GET_CLASS_NAME(@CLASSNO,@CLASSNAME);  
           
         SET @insertSql = CONCAT('INSERT INTO TBL_STUDENT VALUES(?,?,?,?)');  
         PREPARE stmtinsert FROM @insertSql;  
         EXECUTE stmtinsert USING @ID,@NAME,@CLASSNAME,@BIRTH;  
         DEALLOCATE PREPARE stmtinsert;  
    END;  
      
    CALL P_INSERT_STUDENT(1,'xy',1,'2012-10-01 10:20:01');  

 

在第二个存储过程中

①利用SET声明了参数,调用了第一个存储过程

②在第一个存储过程中的NAME参数是输出参数,所以@CLASSNAME这个参数在调用完第一个过程后就被附值

③最终利用CONCAT拼接SQL语句并传入参数执行SQL语句

CALL P_INSERT_STUDENT(1,'xy',1,'2012-10-01 10:20:01');调用存储过程

时间: 2024-12-03 10:12:04

mysql存储过程中的异常处理的相关文章

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

定义异常捕获类型及处理方法:  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

mysql 存储过程中游标临时表问题

问题描述 mysql 存储过程中游标临时表问题 DELIMITER $$ USE laolao$$ DROP PROCEDURE IF EXISTS parent_sport_sort1$$ CREATE DEFINER=root@% PROCEDURE parent_sport_sort1(IN jidb VARCHAR(64),IN uname VARCHAR(64),IN starttime VARCHAR(64),IN endtime VARCHAR(64), IN startmonth

mysql存储过程中变量的定义赋值操作

昨天我们讲了mysql教程存储过程创建修改与删除,下面我们这篇教程是讲关于mysql存储过程中变量的定义赋值操作哦. 一.变量的定义 定义一个变量语法如下: declare var_name[,...] type[default value] 看一个变量定义实例 declare last date; 二.mysql存储过程变量赋值 变量的赋值可直接赋值与查询赋值来操作,直接赋值可以用set来操作,可以是常量或表达式如果下 set var_name= [,var_name expr]... 给上面

mysql 存储过程中使用了游标和临时表,返回的临时表数据不准确

问题描述 mysql 存储过程中使用了游标和临时表,返回的临时表数据不准确 DELIMITER $$ USE laolao$$ DROP PROCEDURE IF EXISTS parent_sport_sort1$$ CREATE DEFINER=root@% PROCEDURE parent_sport_sort1(IN jidb VARCHAR(64),IN uname VARCHAR(64),IN starttime VARCHAR(64),IN endtime VARCHAR(64),

mysql存储过程中动态表名的使用

问题描述 mysql存储过程中动态表名的使用 BEGIN if tablename is not null then declare v_sql varchar(500); set v_sql = concat('select WXPayBillID,WXPayMoney FROM ',tablename); select v_sql; set @v_sql=v_sql;///这里写的有问题? prepare stmt from @v_sql; EXECUTE stmt; deallocate

MySQL存储过程中实现执行动态SQL语句的方法_Mysql

本文实例讲述了MySQL存储过程中实现执行动态SQL语句的方法.分享给大家供大家参考.具体实现方法如下: mysql> mysql> delimiter $$ mysql> mysql> CREATE PROCEDURE set_col_value -> (in_table VARCHAR(128), -> in_column VARCHAR(128), -> in_new_value VARCHAR(1000), -> in_where VARCHAR(4

MySQL存储过程中的事务管理实例说明

mysql存储过程中事务SQL代码  delimiter $$  use test$$  create procedure t_insert_table()  begin      /** 标记是否出错 */      declare t_error int default 0;      /** 如果出现sql异常,则将t_error设置为1后继续执行后面的操作 */      declare continue handler for sqlexception set t_error=1; -

浅谈MySQL存储过程中declare和set定义变量的区别_Mysql

在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅在类中生效.即只在存储过程中的begin和end之间生效. 2.@set定义的变量,叫做会话变量,也叫用户定义变量,在整个会话中都起作用(比如某个应用的一个连接过程中),即这个变量可以在被调用的存储过程或者代码之间共享数据.如何理解呢?可以看下面这个简单例子,很好理解.  (1)先执行下面脚本,创建

mysql 存储过程中游标与多游标实例

例  代码如下 复制代码 DELIMITER $$ DROP PROCEDURE IF EXISTS getUserInfo $$ CREATE PROCEDURE getUserInfo(in date_day datetime) -- -- 实例 -- MYSQL存储过程名为:getUserInfo -- 参数为:date_day日期格式:2008-03-08 --     BEGIN declare _userName varchar(12); -- 用户名 declare _chines