メモ(その2)
delimiter //
drop procedure if exists test_proc;
create procedure test_proc()
language sql
deterministic modifies sql data
comment 'test procedure'
begin
/* 変数宣言 */
declare vc_val varchar(32) default null;
declare vc_version varchar(1024) default null;
/* 条件の定義 */
declare ORG_DUP_VAL_ON_INDEX condition for 1062;
declare ORG_TOO_MANY_ROWS condition for 1172;
/* ハンドラの定義 */
declare continue handler for ORG_DUP_VAL_ON_INDEX
begin
select 'DEBUG handler on ORG_DUP_VAL_ON_INDEX';
end;
declare continue handler for ORG_TOO_MANY_ROWS
begin
select 'DEBUG handler on ORG_TOO_MANY_ROWS';
end;
/* 自動コミットOFF */
set autocommit = 0;
/* 変数に値を代入 */
set vc_val = 'debug';
select vc_val;
/* 関数の実行結果を変数に代入 */
select version() into vc_version;
select vc_version;
delete from tbl1;
delete from tbl2;
commit;
/* トランザクションの開始 */
start transaction;
select 'DEBUG block-1';
begin
/* このハンドラはmysql error code 1048を捕捉します
* ハンドラステートメント実行した後に、このサブブロックから抜けます */
declare exit handler for 1048
begin
select 'DEBUG SQL exception BAD_NULL_ERROR block-1';
end;
select 'block-1 step1';
/* mysql error 1048を発生させる */
insert into tbl1 values (null);
/* これは実行されない */
select 'block-1 step2';
end;
select 'DEBUG block-2';
begin
/* このハンドラはmysql error code 1048を捕捉します
* ハンドラステートメント実行した後に、続きのステートメントを実行します */
declare continue handler for 1048
begin
select 'DEBUG SQL exception BAD_NULL_ERROR block-2';
end;
select 'block-2 step1';
/* mysql error 1048を発生させる */
insert into tbl1 values (null);
/* これは実行される */
select 'block-2 step2';
end;
select 'DEBUG block-3';
begin
/* このハンドラはmysql error code 1062を捕捉します
* ハンドラステートメント実行した後に、このサブブロックから抜けます */
declare exit handler for 1062
begin
select 'DEBUG SQL exception DUP_KEY block-3';
end;
select 'block-3 step1';
insert into tbl1 values (1);
select 'block-3 step2';
/* mysql error 1062を発生させる */
insert into tbl1 values (1);
/* これは実行されない */
select 'block-3 step3';
end;
commit;
start transaction;
select 'DEBUG block-4';
begin
/* 変数宣言 */
declare done int default 0;
/* このハンドラはmysql error code 1062を捕捉します
* ハンドラステートメント実行した後に、続きのステートメントを実行します */
declare continue handler for 1062
begin
set done = 1;
select 'DEBUG SQL exception block-4(1)';
end;
select 'block-4(1) step1';
insert into tbl1 values (2);
select 'block-4(1) step2';
/* mysql error 1062を発生させる */
insert into tbl1 values (2);
/* これは実行される */
select 'block-4(1) step3';
if (done) then
select 'DEBUG block-4(1) exception!';
end if;
select 'DEBUG block-4(2)';
/*
* ネストしたサブブロックの定義
*/
begin
/* このハンドラはmysql sqlstate 23000を捕捉します
* ハンドラステートメント実行した後に、このサブブロックから抜けます */
declare exit handler for 1062
begin
select 'DEBUG SQL exception block-4(2)';
end;
select 'block-4(2) step1';
insert into tbl1 values (3);
select 'block-4(2) step2';
/* mysql error 1062を発生させる */
insert into tbl1 values (3);
/* これは実行されない */
select 'block-4(2) step3';
end;
/* これは実行される */
select 'DEBUG block-4(3)';
end;
commit;
select 'DEBUG block-5';
begin
/* 変数宣言 */
declare vn_p1 int default 0;
select 'block-5 step1';
/* このselect文は複数件レコードを返すのでmysql error 1172を発生させる
* この例外を捕捉するハンドラは、一番外側のブロックで定義した ORG_TOO_MANY_ROWS で捕捉される */
select tbl1.p1 into vn_p1 from tbl1 where p1 > 0;
select 'block-5 step2';
select vn_p1;
select 'block-5 step3';
end;
start transaction;
select 'DEBUG block-6';
begin
select 'block-6 step1';
insert into tbl1 values (4);
select 'block-6 step2';
/* このinsert文はmysql error 1062を発生させる
* この例外を捕捉するハンドラは、一番外側のブロックで定義した ORG_DUP_VAL_ON_INDEX で捕捉される */
insert into tbl1 values (4);
select 'block-6 step3';
end;
commit;
start transaction;
insert into tbl2 values (1,1);
insert into tbl2 values (1,2);
insert into tbl2 values (1,3);
insert into tbl2 values (2,1);
insert into tbl2 values (2,2);
insert into tbl2 values (2,3);
insert into tbl2 values (2,4);
insert into tbl2 values (3,1);
insert into tbl2 values (3,2);
insert into tbl2 values (3,3);
insert into tbl2 values (3,4);
insert into tbl2 values (3,5);
insert into tbl2 values (4,1);
commit;
select 'DEBUG block-7';
begin
/* 変数宣言 */
declare done int default 0;
declare vn_p1 int default 0;
/* カーソル */
declare tbl1_cur cursor for select p1 from tbl1;
declare tbl2_cur cursor for select p1, p2 from tbl2 where p1 = vn_p1;
/* このハンドラはmysqlに組み込みのNOT FOUNDハンドラです
* ハンドラステートメント実行した後に、このサブブロックから抜けます */
declare continue handler for NOT FOUND
begin
set done = 1;
select 'DEBUG handler on outer loop NOT FOUND';
end;
select 'block-7 step1';
open tbl1_cur;
repeat
/* フェッチするレコードが無い場合にNOT FOUNDが発生する */
fetch tbl1_cur into vn_p1;
if not done then
select 'outer loop : ', vn_p1;
begin
/* 変数宣言 */
declare done int default 0;
declare vn_p1 int default 0;
declare vn_p2 int default 0;
declare continue handler for NOT FOUND
begin
set done = 1;
select 'DEBUG handler on inner loop NOT FOUND';
end;
open tbl2_cur;
repeat
fetch tbl2_cur into vn_p1, vn_p2;
if not done then
select 'inner loop : ', vn_p1,vn_p2;
end if;
until done end repeat;
close tbl2_cur;
end;
end if;
until done end repeat;
close tbl1_cur;
select 'block-7 step2';
end;
end;
//
delimiter ;