触发器 函数 存储过程
触发器
before update after update before delete after delete before insert after insert
drop table if exists test; create table test( id int ); insert into test(id) values(1), (2); create table test_trigger( id int ); insert into test_trigger(id) values(1); delimiter $$ create trigger test_t2 after update on test for each row begin update test_trigger set id = 3 where id = 1; end $$ delimiter ;
触发器不能作用于同一个表 触发作用的表, 可以用 old 和 new 来表示 触发前 和 触发后 的表名
函数
函数会绑定数据库
delimiter $$ drop function if exists say ; create function say() returns varchar(20) begin return ‘hello world‘; end $$ delimiter ; select say();
delimiter $$ create function say2(name varchar(10)) returns varchar(20) begin return concat(‘hello world, ‘, name); end $$ delimiter ; select say2(‘Mr‘);
控制语句
if
if isnull(NULL) -- true if !isnull(NULL) -- false
if xxx then xxx elseif xxx then xxx else xxx end if;
delimiter $$ create function func1() returns varchar(20) begin set @cur_h = hour(now()); if @cur_h >= 18 then return ‘night‘; elseif @cur_h > 12 then return ‘afternoon‘; else return ‘morning‘; end if; end $$ delimiter ;
while
delimiter $$ create function func2() returns int begin set @i = 1; set @sum = 0; while @i <= 10 do set @sum = @sum + @i; set @i = @i + 1; end while; return @sum; end $$ delimiter ;
break
delimiter $$ create function func3() returns int begin set @i = 1; set @sum = 0; w: while @i <= 10 do if @i = 5 then leave w; end if; set @sum = @sum + @i; set @i = @i + 1; end while w; return @sum; end $$ delimiter ;
continute
delimiter $$ create function func4() returns int begin set @i = 1; set @sum = 0; w: while @i <= 10 do if @i = 5 then set @i = @i + 1; iterate w; end if; set @sum = @sum + @i; set @i = @i + 1; end while w; return @sum; end $$ delimiter ;
do while
repeat .... until xxx -- 这里没有 ‘;‘ 号 end repeat;
使用局部变量
delimiter $$ drop function if exists my_sum; create function my_sum(start_num int, end_num int) returns int begin declare i int default start_num; set i = 3; -- 报错, 要先声明完, 之后才能定义, 这里先定义了 declare sum int default 0; w: while i <= end_num do set sum = sum + i; set i = i + 1; end while w; return sum; end $$ delimiter ;
delimiter $$ drop function if exists my_sum; create function my_sum(start_num int, end_num int) returns int begin declare i int default start_num; declare sum int default 0; w: while i <= end_num do set sum = sum + i; set i = i + 1; end while w; return sum; end $$ delimiter ;
存储过程
没有返回值的函数
delimiter $$ create procedure p1(n int) begin select n; end $$ delimiter ; call p1(‘abc‘);
delimiter $$ create procedure p2(in n int) begin select n; end $$ delimiter ; call p2(‘abc‘);
delimiter $$ create procedure p3(out n int) begin set n = 3; end $$ delimiter ; call p3(@ans); select @ans;
set @ans = 0; delimiter $$ create procedure p4(inout n int) begin set n = 3; end $$ delimiter ; call p4(@ans); select @ans; -- 3
游标
drop table if exists goods; create table goods ( id int, num int, name varchar(20) ); insert into goods (id, num, name) values (1, 10, ‘one‘), (2, 20, ‘two‘), (3, 30, ‘thr‘); delimiter $$ drop procedure if exists p5; create procedure p5() begin select * from goods; end $$ delimiter ; call p5();
delimiter $$ drop procedure if exists p6; create procedure p6() begin declare row_id int; declare row_num int; declare row_name varchar(20); declare getgoods cursor for select * from goods; open getgoods; fetch getgoods into row_id, row_num, row_name; select row_id, row_num, row_name; fetch getgoods into row_id, row_num, row_name; select row_id, row_num, row_name; close getgoods; end $$ delimiter ; call p6();
delimiter $$ drop procedure if exists p7; create procedure p7() begin declare row_id int; declare row_num int; declare row_name varchar(20); declare i int default 0; declare cnt int default 0; declare getgoods cursor for select * from goods; select count(*) from goods into cnt; open getgoods; while i < cnt do fetch getgoods into row_id, row_num, row_name; select row_id, row_num, row_name; set i = i + 1; end while; close getgoods; end $$ delimiter ; call p7();
-- 报错, 要先定义 游标变量, 然后定义 end_of_cursor 最后定义 handler... -- ERROR 1337 (42000): Variable or condition declaration after cursor or handler declaration delimiter $$ drop procedure if exists p8; create procedure p8() begin declare row_id int; declare row_num int; declare row_name varchar(20); declare getgoods cursor for select * from goods; declare end_of_cursor int default 0; declare continue handler for not found set end_of_cursor = 1; open getgoods; while end_of_cursor = 0 do fetch getgoods into row_id, row_num, row_name; select row_id, row_num, row_name; end while; close getgoods; end $$ delimiter ; call p8();
-- 会多取一次 delimiter $$ drop procedure if exists p8; create procedure p8() begin declare row_id int; declare row_num int; declare row_name varchar(20); declare end_of_cursor int default 0; declare getgoods cursor for select * from goods; declare continue handler for not found set end_of_cursor = 1; open getgoods; repeat fetch getgoods into row_id, row_num, row_name; select row_id, row_num, row_name; until end_of_cursor = 1 end repeat; close getgoods; end $$ delimiter ; call p8();
delimiter $$ drop procedure if exists p9; create procedure p9() begin declare row_id int; declare row_num int; declare row_name varchar(20); declare end_of_cursor int default 0; declare getgoods cursor for select * from goods; declare continue handler for not found set end_of_cursor = 1; -- 判断到最后 open getgoods; while end_of_cursor = 0 do fetch getgoods into row_id, row_num, row_name; if end_of_cursor != 1 then -- 不加这句话会多取一次, 上面的 handle 表示判断到最后还是 continue select row_id, row_num, row_name; end if; end while; close getgoods; end $$ delimiter ; call p9();
delimiter $$ drop procedure if exists p10; create procedure p10() begin declare row_id int; declare row_num int; declare row_name varchar(20); declare end_of_cursor int default 0; declare getgoods cursor for select * from goods; declare exit handler for not found set end_of_cursor = 1; -- 判断到了最后, 后面的代码不再继续执行 open getgoods; while end_of_cursor = 0 do fetch getgoods into row_id, row_num, row_name; select row_id, row_num, row_name; end while; close getgoods; end $$ delimiter ; call p10();
continue, exit, undo (undo 是到了最后, 前面的代码不再执行) handle for not found set xxx = xxxx