|
MySQL存储过程 ERROR Handler 异常处理
问题样例:当insert失败时,我希望将其记录在日志文件中,
》》在这里需要创建一个主键表,以及一个外键表,我们使用的是Innodb ,因此外键关联检查是打开的,当我向外键表中插入
非主键表中的值时,动作将会失败,创建的数据表如下:
create table t2(s1 int primary key)engine=innodb;//
create table t3(s1 int,
key(s1),
foreign key (s1) references t2(s1))engine=innodb;//
create table error_log(error_message char(80));//
1. 建立一个过程,第一个语句 DECLARE EXIT HANDLER是用来处理异常的,意思是如果错误 1216发生,这个程序将会在错误记录表中插入一行,
EXIT的意思是 当动作成功提交后推出这个复合语句。
create procedure p22(parameter int)
begin
declare exit Handler for 1452
insert into error_log values(concat('Time: ',current_date,'.Foreign key reference failure for value=',parameter));
insert into t3 values(parameter);
end;//
2. 申明异常处理的语法 DECLARE HANDLER syntax:
DECLARE {EXIT|CONTINUE} HANDLER FOR {error_number|{SQLSTATE error-string}|condition} SQL Statement
上面就是错误处理的用法,也就是一段当程序出错后自动触发的代码,MYSQL允许两种处理器,一种是exit处理,另外一种是 continue处理,与exit
不同的是在于他执行后,原主程序仍然继续运行,那么该复合语句就没有出口了。
----continue处理的例子:
create table t4(s1 int primary key);//
create procedure p23()
begin
declare continue handler for SQLSTATE '23000' set @x2=1;
set @x=1;
insert into t4 values (1);
set @x=2;
insert into t4 values(1);
set @x=3;
select @x, @x2;
end;//
call p23();//
---- rollback(回滚事务),定义自己的错误处理名字 declare '错误处理名' condition for SQLSTATE'23000';
create procedure p24()
begin
declare ViolationSelf condition for SQLSTATE'23000';
DECLARE EXIT HANDLER for ViolationSelf rollback;
start transaction;
insert into t2 values(1);
insert into t2 values(1);
commit;
end;//
/******************************************** Cursor游标 **********************************************************/
游标实现功能的摘要: 声明游标, 打开游标,从游标里读取,关闭游标
DECLARE cursor-name CURSOR FOR SELECT ······
OPEN cursor-name;
FETCH cursor-name INTO variable;
CLOSE cursor-name;
1. create procedure p25(out return_val int)
begin
DECLARE a,b,c int;
DECLARE cur_1 CURSOR for select s1 from t;
DECLARE continue handler for not found set b=1;
open cur_1;
set c=0;
repeat
fetch cur_1 into a;
until b=1
end repeat;
close cur_1;
set return_val=a;
end;//
2. create procedure p25_1(out return_val int)
begin
DECLARE a,b,c int;
DECLARE cur_1 CURSOR for select s1 from t;
DECLARE continue handler for not found set b=1;
open cur_1;
set c=0;
lable_1:loop
fetch cur_1 into a;
if b=1 then
leave lable_1;
end if;
set c=c+1;
end loop;
close cur_1;
set return_val=c;
end;//
create procedure p34(in va int)
begin
delete from t where s1=va;
end;//
http://www.docin.com/p-68861166.html
http://www.111cn.net/database/11 ... 9b42e2754a69e5d.htm
Error Handler Examples
Here are some examples of handler declarations:
If any error condition arises (other than a NOT FOUND ), continue execution after setting l_error=1 :
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET l_error=1;
If any error condition arises (other than a NOT FOUND ), exit the current block or stored program after issuing a ROLLBACK statement and issuing an error message:
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'Error occurred – terminating';
END;
If MySQL error 1062 (duplicate key value) is encountered, continue execution after executing the SELECT statement (which generates a message for the calling program):
DECLARE CONTINUE HANDER FOR 106 2
SELECT 'Duplicate key in index';
If SQLSTATE 23000 (duplicate key value) is encountered, continue execution after executing the SELECT statement (which generates a message for the calling program):
DECLARE CONTINUE HANDER FOR SQLSTATE '23000'
SELECT 'Duplicate key in index';
When a cursor fetch or SQL retrieves no values, continue execution after setting l_done=1 :
DECLARE CONTINUE HANDLER FOR NOT
FOUND
SET l_done=1;
Same as the previous example, except specified using a SQLSTATE variable rather than a named condition:
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000 '
SET l_done=1;
Same as the previous two examples, except specified using a MySQL error code variable rather than a named condition or SQLSTATE variable:
DECLARE CONTINUE HANDLER FOR 1329
SET l_done=1;
错误处理例子
有几种错误处理的声明形式:
§ 如果任何错误(不是 NOT FOUND ) , 设置 l_error 为 1 后继续执行:
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET l_error=1;
§ 如果发生任何错误(不是 NOT FOUND), 执行 ROLLBACK和产生一条错误消息后退出当前块或存储过程。
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'Error occurred – terminating';
END;
§ 如果 MySQL 1062错误 (重复的健值 )发生,执行 SELECT语句(向调用程序发一条消息)后继续执行
DECLARE CONTINUE HANDER FOR 106 2
SELECT 'Duplicate key in index';
§ 如果 SQLSTATE 2300错误 (重复的健值 )发生,执行 SELECT语句(向调用程序发一条消息)后继续执行
DECLARE CONTINUE HANDER FOR SQLSTATE '23000'
SELECT 'Duplicate key in index';
§ 当游标或者 SQL 选择语句没有返回值时,设置 l_done=1 后继续执行
DECLARE CONTINUE HANDLER FOR NOT
FOUND
SET l_done=1;
§ 此例除了用 SQLSTATE 变量而不是命名条件以外,跟前一个例子一样
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000 '
SET l_done=1;
§ 此例除了用 MySQL 的错误码变量而不是命名条件或者 SQLSTATE 变量以外,跟前两个例子一样
DECLARE CONTINUE HANDLER FOR 1329
SET l_done=1;
http://www.jb51.net/article/20513.htm
http://www.360doc.com/content/11/0623/16/61497_129060932.shtml
http://www.phper-seoer.com/php/176.html
定义错误:
为错误定义一个名称,语法为:
DECLARE error_name CONDITION FOR condition_value;
declare 定义一个变量
error_name:自定义的错误的名字
condition_value可以是两种情况:
第一:直接写错误号,如 1305;
错误代码
第二:写sqlstate错误号: 如
SQLSTATE '42000';
sqlstate错误号
错误处理
语法为:
DECLARE handler_type HANDLER FOR condition_value
begin
...
end;
handler_type: 处理的过程。
CONTINUE 继续执行未完成的存储过程,直至结束。(常用,默认)
| EXIT 出现错误即自动跳出所在的begin不再执行后面的语句。
condition_value: 处理的触发条件
SQLSTATE [VALUE] sqlstate_value 不用说了,就是上面提到的第二中方法,也是最常用的错误定义,自己去查错误列表吧。
| condition_name 我们刚刚定义的那个名字errorname就是用在这里的。
| SQLWARNING 代表所有以01开头的错误代码
| NOT FOUND 表所有以02开头的错误代码,当然也可以代表一个游标到达数据集的末尾。
| SQLEXCEPTION 代表除了SQLWARNING和NOT FOUND 的所有错误代码。
| mysql_error_code 错误编号,上面的第一种方法,不过同样可以在错误列表从中查到,是我比较常用的。
例子:
create procedure error_test()
begin
#定义错误,1305是调用了错误的存储过程
declare errname condition for 1305;
declare continue handler for errname
begin
select 'no that procedure' as error;
end;
call aaa();end;
备注:
MySQL ERROR CODE 列表
如果需要查看更多的错误列表可以直接到MySQL安装路径下。
比如我的/usr/local/mysql/share/mysql/errmsg.txt
说明:SQLSTATE [VALUE] sqlstate_value这种格式是专门为ANSI SQL 和 ODBC以及其他的标准.
并不是所有的MySQL ERROR CODE 都映射到SQLSTATE。 |
|