作者:mysqlAB;翻译:陈朋奕
ErrorHandling异常处理
好了,我们现在要讲的是异常处理
1.SampleProblem:LogOfFailures问题样例:故障记录
当INSERT失败时,我希望能将其记录在日志文件中我们用来展示出错处理的问题样例是很
普通的。我希望得到错误的记录。当INSERT失败时,我想在另一个文件中记下这些错误的
信息,例如出错时间,出错原因等。我对插入特别感兴趣的原因是它将违反外键关联的约束
2.SampleProblem:LogOfFailures(2)
mysql>CREATETABLEt2
s1INT,PRIMARYKEY(s1))
engine=innodb;//
mysql>CREATETABLEt3(s1INT,KEY(s1),
FOREIGNKEY(s1)REFERENCESt2(s1))
engine=innodb;//
mysql>INSERTINTOt3VALUES(5);//
...
ERROR1216(23000):Cannotaddorupdateachildrow:aforeignkey
constraintfails(这里显示的是系统的出错信息)
我开始要创建一个主键表,以及一个外键表。我们使用的是InnoDB,因此外键关联检查是打
开的。然后当我向外键表中插入非主键表中的值时,动作将会失败。当然这种条件下可以很
快找到错误号1216。
3.SampleProblem:LogOfFailures
CREATETABLEerror_log(error_message
CHAR(80))//
下一步就是建立一个在做插入动作出错时存储错误的表。
4.SampleProblem:LogOfErrors
CREATEPROCEDUREp22(parameter1INT)
BEGIN
DECLAREEXITHANDLERFOR1216
INSERTINTOerror_logVALUES
(CONCAT('Time:',current_date,
'.ForeignKeyReferenceFailureFor
Value=',parameter1));
INSERTINTOt3VALUES(parameter1);
END;//
上面就是我们的程序。这里的第一个语句DECLAREEXITHANDLER是用来处理异常的。意思是如果错误1215发生了,这个程序将会在错误记录表中插入一行。EXIT意思是当动作成功提交后退出这个复合语句。
5.SampleProblem:LogOfErrors
CALLp22(5)//
调用这个存储过程会失败,这很正常,因为5值并没有在主键表中出现。但是没有错误信息
返回因为出错处理已经包含在过程中了。t3表中没有增加任何东西,但是error_log表中记录
下了一些信息,这就告诉我们INSERTintotablet3动作失败。
DECLAREHANDLERsyntax声明异常处理的语法
DECLARE
{EXIT|CONTINUE}
HANDLERFOR
{error-number|{SQLSTATEerror-string}|condition}
SQLstatement
上面就是错误处理的用法,也就是一段当程序出错后自动触发的代码。MySQL允许两种处理器,一种是EXIT处理,我们刚才所用的就是这种。另一种就是我们将要演示的,CONTINUE处理,它跟EXIT处理类似,不同在于它执行后,原主程序仍然继续运行,那么这个复合语句就没有出口了。
1.DECLARECONTINUEHANDLERexampleCONTINUE处理例子
CREATETABLEt4(s1int,primarykey(s1));//
CREATEPROCEDUREp23()
BEGIN
DECLARECONTINUEHANDLER
FORSQLSTATE'23000'SET@x2=1;
SET@x=1;
INSERTINTOt4VALUES(1);
SET@x=2;
INSERTINTOt4VALUES(1);
SET@x=3;
END;//
这是MySQL参考手册上的CONTINUE处理的例子,这个例子十分好,所以我把它拷贝到这里。
通过这个例子我们可以看出CONTINUE处理是如何工作的。
2.DECLARECONTINUEHANDLER声明CONTINUE异常处理
CREATETABLEt4(s1int,primarykey(s1));//
CREATEPROCEDUREp23()
BEGIN
DECLARECONTINUEHANDLER
FORSQLSTATE'23000'SET@x2=1;<--
SET@x=1;
INSERTINTOt4VALUES(1);
SET@x=2;
INSERTINTOt4VALUES(1);
SET@x=3;
END;//
这次我将为SQLSTATE值定义一个处理程序。还记得前面我们使用的MySQL错误代码1216吗?
事实上这里的23000SQLSTATE是更常用的,当外键约束出错或主键约束出错就被调用了。1