文章目录:
3.4 删除存储过程
DROP PROCEDURE [IF EXISTS] sp_name;
3.5 存储过程中常用语法
通过 DECLARE 可以定义一个局部变量,该变量的作用范围只能在 BEGIN…END 块中。
直接赋值使用 SET,可以赋常量或者赋表达式,具体语法如下:
DECLARE var_name[,...] type [DEFAULT value] SET var_name = expr [, var_name = expr] ...
也可以通过select ... into 方式进行赋值操作 :
if search_condition then statement_list [elseif search_condition then statement_list] ... [else statement_list] end if;
create procedure procedure_name([in/out/inout] 参数名 参数类型) ... IN : 该参数可以作为输入,也就是需要调用方传入值 , 默认 OUT: 该参数作为输出,也就是该参数可以作为返回值 INOUT: 既可以作为输入参数,也可以作为输出参数
@description : 这种变量要在变量名称前面加上“@”符号,叫做用户会话变量,代表整个会话过程他都是有作用的,这个类似于全局变量一样。
@@global.sort_buffer_size : 这种在变量前加上 "@@"符号, 叫做系统变量
CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] ... [ELSE statement_list] END CASE;
while search_condition do statement_list end while;
有条件的循环控制语句, 当满足条件的时候退出循环。while 是满足条件才执行,repeat 是满足条件就退出循环。
REPEAT statement_list UNTIL search_condition END REPEAT;
LOOP实现简单的循环,退出循环的条件需要使用其他的语句定义,通常可以使用 LEAVE 语句实现,具体语法如下:
[begin_label:] LOOP statement_list END LOOP [end_label]
如果不在 statement_list 中增加退出循环的语句,那么 LOOP 语句可以用来实现简单的死循环。
游标是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用光标对结果集进行循环的处理。光标的使用包括光标的声明、OPEN、FETCH 和 CLOSE,其语法分别如下。
声明光标:
DECLARE cursor_name CURSOR FOR select_statement;
OPEN光标:
OPEN cursor_name;
FETCH光标:
FETCH cursor_name INTO var_name [, var_name] ...
CLOSE光标:
CLOSE cursor_name;
下面,为了演示光标的案例,先创建一张emp表。
create table emp( id int(11) not null auto_increment , name varchar(50) not null comment '姓名', age int(11) comment '年龄', salary int(11) comment '薪水', primary key(`id`) )engine=innodb default charset=utf8; insert into emp(id,name,age,salary) values(null,'金毛狮王',55,3800),(null,'白眉鹰王',60,4000),(null,'青翼蝠王',38,2800),(null,'紫衫龙王',42,1800);
下面第一种方法是逐行获取光标,从中取出数据。
上面逐行获取的方法虽然可行,但是如果数据过多,则显得代码量较大、冗余度较高。
所以下面采用repeat循环的方法来获取光标。(截图中的Display请忽略,应该是粘贴的时候格式有点问题)
3.6 存储函数
CREATE FUNCTION function_name([param type ... ]) RETURNS type BEGIN ... END;
4.触发器
触发器是与表有关的数据库对象,指在insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作。
使用别名 OLD 和 NEW 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。
4.1 创建触发器
create trigger trigger_name before/after insert/update/delete on tbl_name [ for each row ] -- 行级触发器 begin trigger_stmt ; end;
为了测试,这里首先创建一张emp_logs表,用来记录触发器相关的操作日志信息。
create table emp_logs( id int(11) not null auto_increment, operation varchar(20) not null comment '操作类型, insert/update/delete', operate_time datetime not null comment '操作时间', operate_id int(11) not null comment '操作表的ID', operate_params varchar(500) comment '操作参数', primary key(`id`) )engine=innodb default charset=utf8;
创建完insert型触发器之后,执行两条insert语句,即可在 emp_logs 表中看到信息。
create trigger emp_logs_insert_trigger after insert on emp for each row begin insert into emp_logs(id,operation,operate_time,operate_id,operate_params) values(null,'insert',now(),new.id,concat('插入后(id:',new.id,', name:',new.name,', age:',new.age,', salary:',new.salary,')')); end$ insert into emp(id,name,age,salary) values(null, '光明左使',30,3500); insert into emp(id,name,age,salary) values(null, '光明右使',33,3200);
创建完update型触发器之后,执行update语句,即可在 emp_logs 表中看到信息。
1. create trigger emp_logs_update_trigger
2. after update
3. on emp
4. for each row
5. begin
6. insert into emp_logs(id,operation,operate_time,operate_id,operate_params)
7. values(null,'update',now(),new.id,concat('修改前(id:',old.id,', name:',old.name,',
8. age:',old.age,', salary:',old.salary,') , 修改后(id',new.id, 'name:',new.name,',
9. age:',new.age,', salary:',new.salary,')'));
10. end$
11.
12. update emp set age = 39 where id = 3;
创建完delete型触发器之后,执行delete语句,即可在 emp_logs 表中看到信息。
create trigger emp_logs_delete_trigger after delete on emp for each row begin insert into emp_logs(id,operation,operate_time,operate_id,operate_params) values(null,'delete',now(),old.id,concat('删除前(id:',old.id,', name:',old.name,', age:',old.age,', salary:',old.salary,')')); end$ delete from emp where id = 5;
4.2 查看触发器
show triggers;
4.3 删除触发器
drop trigger [schema_name.]trigger_name;