一 存储过程
什么是存储过程 : 自己搜
和代码写的有什么区别: 没区别
为什么用存储过程: 快
例子
-- 创建 test名字的存储过程
CREATE PROCEDURE `test`(in idin INT)
BEGIN-- 创建变量declare id int default 0;declare stopflag int default 0;declare username varchar(31) default '';-- 创建游标declare item cursor for select u.router_id id, u.`name` username from base_router u where u.router_status = idin;-- 出现异常时执行功能(可做循环结束判断)declare continue handler for not found set stopflag = 1;-- 打开游标OPEN item;-- 创建一个名字为 loop_lable 的loop循环loop_lable: LOOP-- 将游标的一行注入变量里fetch item into id, username;-- if判断是否结束IF stopflag = 1 THEN-- 结束 循环结束LEAVE loop_lable; END IF;-- 业务逻辑处理BEGINIF id = 5 THENUPDATE base_router r SET r.create_user = '10001' WHERE r.router_id = id;ELSEUPDATE base_router r SET r.update_user = '10001' WHERE r.router_id = id;END IF;END;-- loop 结束语句END LOOP loop_lable;-- 执行完成关闭游标close item;
END
解析:
1. 创建存储过程:procedure
create procedure procedure_name(in itemIn int, inout itemOut int, out itemOut int)
begin
...
end;
-- in 传递参数
-- out 输出参数
-- inout 传递参数并输出
-- procedure_name 存储过程名称
2. 调用存储过程 : call
call name();-- 传递参数set @item = ''call name(@item);select @item
3. 变量: declare
begin-- 创建参数,并指定参数类型,默认值declare item varchar(31) default '';-- 使用 set 赋值set item = 'bianlaing';-- 使用 into 赋值select name into item from user where 1 = 1;
end;
4. 变量的作用于只在begin - end 之间,begin - end 可以有多层,可设置全局变量
begindeclare item varchar(31) default '';begin...end
end
5. 条件语句
-- if格式: if boolean then...elseif boolean then...else ...end if;
-- case格式:case itemwhen boolean then ...when boolean then ...else ...end case;
6. 循环
-- while 循环
while(boolean) do
...
end while;
-- repeat 循环
repeat begin...end;
-- 达成条件结束 为true时结束,与while条件相反
until boolean
end repeat;
-- loop循环
loop_name: loop if boolean then leave loop_name;else...end if;...
end loop loop_name;
7. 游标 : cursor
代表结果集,可对结果集进行循环
-- 创建 test名字的存储过程
CREATE PROCEDURE `test`(in idin INT)
BEGIN-- 创建变量declare id int default 0;declare stopflag int default 0;declare username varchar(31) default '';-- 创建游标declare item cursor for select u.router_id id, u.`name` username from base_router u where u.router_status = idin;-- 游标出现异常时执行功能(可做循环结束判断)declare continue handler for not found set stopflag = 1;-- 打开游标OPEN item;-- 创建一个名字为 loop_lable 的loop循环loop_lable: LOOP-- 将游标的一行注入变量里fetch item into id, username;-- if判断是否结束IF stopflag = 1 THEN-- 结束 循环结束LEAVE loop_lable; END IF;-- 业务逻辑处理BEGIN...END;-- loop 结束语句END LOOP loop_lable;-- 执行完成关闭游标close item;
END
二 触发器
关键词:TRIGGER
-- 触发器共有三种:insert,update,delete
-- 触发事件有两种:after, before
-- 触发器的参数只有两种: new,old insert 只能用new delete 只能用old updata 修改前的用old,修改后的用new
-- 触发器查看: show TRIGGERS; 或者选择 on 后边的主表,可以查看触发器(navicat),plsql可以直接看trigger
CREATE TRIGGER test_updata AFTER INSERT ON test1FOR EACH ROWBEGININSERT INTO test2(id,name,status) VALUES (new.id, new.name,new.status);END;
关于触发器在哪看
- show TRIGGERS
- AFTER INSERT ON test1 的表里
三 事件
就是定时任务
关键词 event
规则
CREATE Event [IF NOT EXISTS] event_name -- 创建使用create event
ON SCHEDULE schedule_time-- on schedule 什么时候来执行,执行频率
-- on schedule at '2023-02-01 04:00:00’ 指定时间
-- on schedule every 1 second 每秒执行一次
-- 也可以是 minute、hour、day、week、month、year
-- on schedule every 1 day starts ‘2023-02-01 04:00:00' 指定每次的指定时间
[ON COMPLETION [NOT] PRESERVE] -- 调度计划执行完成后是否还保留
[ENABLE | DISABLE] -- 是否生效事件
[COMMENT 'comment'] -- 事件的注释
DO event_body; -- 这个调度计划要做什么?
例子
CREATE EVENT `test_event`
ON SCHEDULE AT '2023-08-09 11:45:00'
ON COMPLETION PRESERVE
ENABLE
DO INSERT INTO test1(id,name,status) VALUES (3, '张三','1');
事件在哪
- show events;
2. navcat
写在最后:
在理论上,数据库的存储过程、触发器、事件 都可以用代码替代,就是一串逻辑、定时任务等。但为啥推荐使用数据库上的功能呢?
1. 可读性 – 比看代码掉的头发少
2. 速度快 – 全在库内执行,不需要先取出来 再添加逻辑,再插入 ,减少数据库访问
3. 减少网络延迟 – 一般情况下数据库和程序不在同一个服务器上,还要访问