MySQL存储过程中一些基本的异常处理教程
有时候,不希望存储过程抛出错误中止执行,而是希望返回一个错误码。Mysql支持异常处理,通过定义CONTINUE/EXIT异常处理的HANDLER来捕获SQLWARNING/NOTFOUND/SQLEXCEPTION(警告/无数据/其他异常)。其中,FOR后面可以改为SQLWARNING,NOTFOUND,SQLEXCEPTION来指示所有异常都处理,相当于oracle中的others。例如,当不进行异常处理时,以下代码将直接抛出一个ERROR1062(23000)错误:
CREATEPROCEDUREtest_proc_ins1( INi_idINT, INi_nameVARCHAR(100) ) BEGIN INSERTINTOtestprocVALUES(i_id,i_name); INSERTINTOtestprocVALUES(i_id,i_name); END;
经过异常处理后,可以避免抛出错误,而是定义一个返回参数o_ret赋予特殊值来表示失败,这样,比如在java代码中,可以通过获取返回值而不是捕获异常的方式来处理业务逻辑。例如将返回值设置为-1:
CREATEPROCEDUREtest_proc_ins1( INi_idINT, INi_nameVARCHAR(100), OUTo_retINT) BEGIN DECLAREEXITHANDLERFORSQLSTATE'23000'seto_ret=-1; --也可以这样使用: --DECLAREEXITHANDLERFORSQLWARNING,NOTFOUND,SQLEXCEPTIONseto_ret=-1; INSERTINTOtestprocVALUES(i_id,i_name); INSERTINTOtestprocVALUES(i_id,i_name); seto_ret=1; END;
当然,对于特定的SQL语句,也可以指定比如主键冲突,就rollback;
DECLAREexitHANDLERFORSQLSTATE'23000' delimiter// CREATEPROCEDURETEST() BEGIN DECLAREexitHANDLERFORSQLEXCEPTION,SQLWARNING,NOTFOUND begin rollback; insertintobbvalues('error'); end; STARTTRANSACTION; INSERTINTOaaVALUES(1); INSERTINTOaaVALUES(2); COMMIT; END; // CALLtest()//