declare handler 聲明異常處理的語法


聲明異常處理的語法

DECLARE
{EXIT | CONTINUE}
HANDLER FOR
{error-number | SQLSTATE error-string | condition}
SQL statement

上述定義包括:

Handler Type (CONTINUE,EXIT)//處理類型 繼續或退出

Handler condition (SQLSTATE,MYSQL ERROR,CONDITION)//觸發條件

Handler actions(錯誤觸發的操作)


注意:

1、exit只退出當前的block。exit 意思是當動作成功提交後,退出所在的複合語句。即declare exit handler for... 所在的複合語句。

2、如果定義了handler action,會在continue或exit之前執行


發生錯誤的條件有:

1、MYSQL錯誤代碼

2、ANSI-standard SQLSTATE code

3、命名條件。可使用系統內置的SQLEXCEPTION,SQLWARNING和NOT FOUND


例1:

當錯誤代碼爲1062時將duplicate_key的值設爲1,並繼續執行當前任務

declare continue handler for 1062 set duplicate_key=1;

下面的跟上面一樣,只是使用的條件爲ANSI標準錯誤代碼

declare continue handler for sqlstate '23000' set duplicate_key=1;

當發生SQLEXCEPTION時,將L_error設爲1,並繼續

declare continue handler for SQLEXCEPTION set L_error=1;


小提示:

當你在MYSQL客戶端執行命令併產生錯誤時,會得到MYSQL和ANSI的SQLSTATE code,如:


附常見錯誤號對照表

MySQL error code SQLSTATE code Error message

1011 HY000 Error on delete of '%s' (errno: %d)
1021 HY000 Disk full (%s); waiting for someone to free some space . . .
1022 23000 Can't write; duplicate key in table '%s'
1027 HY000 '%s' is locked against change
1036 HY000 Table '%s' is read only
1048 23000 Column '%s' cannot be null
1062 23000 Duplicate entry '%s' for key %d
1099 HY000 Table '%s' was locked with a READ lock and can't be updated
1100 HY000 Table '%s' was not locked with LOCK TABLES
1104 42000 The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay
1106 42000 Incorrect parameters to procedure '%s'
1114 HY000 The table '%s' is full
1150 HY000 Delayed insert thread couldn't get requested lock for table %s
1165 HY000 INSERT DELAYED can't be used with table '%s' because it is locked with LOCK TABLES
1242 21000 Subquery returns more than 1 row
1263 22004 Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld
1264 22003 Out of range value adjusted for column '%s' at row %ld
1265 1000 Data truncated for column '%s' at row %ld
1312 0A000 SELECT in a stored program must have INTO
1317 70100 Query execution was interrupted
1319 42000 Undefined CONDITION: %s
1325 24000 Cursor is already open
1326 24000 Cursor is not open
1328 HY000 Incorrect number of FETCH variables
1329 2000 No data to FETCH
1336 42000 USE is not allowed in a stored program
1337 42000 Variable or condition declaration after cursor or handler declaration
1338 42000 Cursor declaration after handler declaration
1339 20000 Case not found for CASE statement
1348 HY000 Column '%s' is not updatable
1357 HY000 Can't drop a %s from within another stored routine
1358 HY000 GOTO is not allowed in a stored program handler
1362 HY000 Updating of %s row is not allowed in %s trigger
1363 HY000 There is no %s row in %s trigger


命名條件:

declare conditon_name condition for {SQLSTATE sqlstate_code | MYSQL_ERROR_CODE};


例如:

declare foreign_key_error condition for 1216;

declare continue handler for foreign_key_error mysql_statements;

優先級:當同時使用MYSQL錯誤碼,標準SQLSTATE錯誤碼,命名條件(SQLEXCEPTION)來定義錯誤處理時,其捕獲順序是(只捕獲一條錯誤):MYSQL碼->SQLSTATE->命名條件


作用域:

1、包括begin...end內的語句

declare continue handler for 1048 select 'attempt to insert a null value';
begin
  insert into a values(6,null);
end;

若a表第二字段定義爲非空,則會觸發1048錯誤


2、若錯誤處理在begin...end內定義,則在之外的語句不會觸發錯誤發生

BEGIN
  BEGIN
    DECLARE CONTINUE HANDLER FOR 1216 select 'Foreign key constraint violated';
  END;
  INSERT INTO departments (department_name,manager_id,location) VALUES ('Elbonian HR','Catbert','Catbertia');
END;


3、能夠捕獲其它存儲過程拋出的錯誤


下面再通過幾個例子來掌握MySQL存儲過程中異常處理的使用。

例一:error-number

準備工作

CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
複製代碼
CREATE TABLE `t2` (
  `cid` INT(10) UNSIGNED NULL DEFAULT NULL,
  INDEX `FK__t1` (`cid`),
  CONSTRAINT `FK__t1` FOREIGN KEY (`cid`) REFERENCES `t1` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
複製代碼

創建存儲過程 

複製代碼
delimiter //
create procedure a(var1 int)
begin
  declare exit handler for 1452 insert into error_log values(
    concat('time:',current_date,'.Foreign Key Reference Failure For Value=',var1)
  );
  insert into t2 values(var1);
end;//
複製代碼

如果有1452錯誤,則當插入到表error_log這個語句完成後,退出(exit),這裏申明異常處理的語句在上面begin...end的複合語句中,所以這裏退出,其實就表示退出了該存儲過程。


例二:sqlstate error-string

準備工作

CREATE TABLE `t4` (
  `id` INT(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

 

複製代碼
create procedure p23()
begin
  begin
  declare exit handler for sqlstate '23000' set @x2=1;
    set @x=1;
    insert into t4 values(1);
    set @x=2;
  end;
  begin
    declare exit handler for sqlstate '23000' set @x2=9;
    insert into t4 values(1);
  end;
  set @x=3;
end
複製代碼

結果:


例三:

複製代碼
begin
  declare exit handler for sqlstate '23000' set @x2=1;
  set @x=1;
  insert into t4 values(1);
  set @x=2;
  begin
    declare exit handler for sqlstate '23000' set @x2=9;
    insert into t4 values(1);
  end;
  set @x=3;
end
複製代碼

結果:

在執行一次該存儲過程,得到結果如下:


error-number的例子

複製代碼
create procedure p22(var1 int)
begin
  declare exit handler for 1216 insert into error_log values(
    concat('time:' , current_date , '.Foreign Key Reference Failure For Value='
    ,var1)
  );
  insert into t3 values(var1);
end;//
複製代碼


sqlstate error-string的例子

複製代碼
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;
end;//
複製代碼

執行結果:


condition的例子

declare 'name' condition for sqlstate '23000';
declare exit handler for 'name' rollback;

 


原文地址:http://www.cnblogs.com/datoubaba/archive/2012/06/20/2556428.html



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章