create trigger 名称 before/after insert on tb1 for each row begin SQL语句; END // # 在表执行XX命令前/后时,开始执行 另一条语句
begin 的SQL语句可以使用NEW来取得插入的一行数据,也可以用NEW.XX来取得插入数据的某一列 删除时可以用到OLD,更新时就有NEW和OLD 比如 begin insert into t2(tname) values(NEW.sname)
创建完之后应该改回来 delimiter ;
有插入删除更新 insert delete update
函数:
内置函数
对时间进行修剪(假如time 为 2020-1-1) select date_format(time,"%Y-%m") from t1 group date_format(time,"%Y-%m") 这样就可以通过年月对表信息进行分组
自定义函数
delimiter \\ create function f1( i1 int,i2 int) returns int # 限定参数和返回的值只能是int类型 BEGIN declare num int; # 声明变量,还可以在声明变量时赋值 declare num int default 0 ; set num = i1+i2; return(num) END \\ delimiter; select f1(1,2); 结果就是3 不然在过程中执行select * from t1;之类的
如果出现1418错误可以使用以下方法:
在客户端上执行SET GLOBAL log_bin_trust_function_creators = 1;
简单存储过程 delimiter \\ create procedure p1() BEGIN select * from t1; insert into t1(id) values(1) END \\ delimiter ; call p1() Python中用cursor.callproc('p1')
传参数(in、out(跟return差不多)、inout) delimiter \\ create procedure p1( in n1 int, out n2 int ) BEGIN select * from t1 where id > n1; n2 = n1 END \\ delimiter ; set @v1 = 0 call p1(2,@v1) # 相当于把V1当成n2传进去 select @V1; cursor.callproc('p1',(2,X))
特性:
可传参: in out inout
虽然没有return 但是可以用out伪造一个return
为什么有结果集,又有out伪造的返回值? 用于表示存储过程的执行结果(看下面的例子)
事务:
delimiter \\ create procedure p1( out n1 tinyint ) BEGIN # 声明如果出现异常所执行的语句 DECLARE exit handler for sqlexception BEGIN -- ERROR set n1 =1; # 如果执行失败 n1=1 rollback; # 执行回滚 END; START TRANSACTION; # 开始事务 select * from t1 where id > n1; COMMIT; # 如果执行没有出错就提交 -- SUCCESS set n1 = 2 # 如果执行成功 n1=2 END \\ delimiter ;
游标:(可以在MySQL中简单实现一些循环)
使用思路
声明游标
获取A表数据中取数据 my_cursor select aid,anum from A
for row_id,row_num in my_cursor : # 检测循环是否有数据,如果无数据就 break (要自己检测) insert into B(bnum) values(row_id+row_num)
示例 delimiter \\ create procedure p1() BEGIN declare row_id int ; # 自定义变量1 declare row_num int ; # 自定义变量2 declare done INT DEFAULT FALSE ; # 初始为FALSE,判断循环是否终止
declare my_cursor CURSOR FOR select aid,anum from A ; # 定义游标,从表A中获取数据 declare CONTINUE HANDLER FOR NOT FOUND SET done = TRUE ; # 判断,当没有数据时设done=TRUE open my_cursor; # 光标开始执行 xxoo:LOOP # 开始循环,循环名为xxoo fetch my_cursor into row_id,row_num; # 获取row_id和row_num if done then # 如果done为TRUE就离开循环 leave xxoo; END IF;
insert into B(num) values(row_id+row_num); end loop xxoo; close my_cursor END \\ delimiter ;
动态执行SQL(防SQL注入) delimiter \\ create procedure p1( in arg int ) BEGIN 1.预检测 SQL语句的合法性 2.初始化SQL=tpl+arg 3.执行SQL语句 set @v1 = arg; PREPARE prod FROM 'select * from A where id > ?'; EXECUTE prod USING @v1; # 只接受会话级别的变量,把?替换成@v1 DEALLOCATE prepare prod ; # 执行SQL END \\ delimiter ;