存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的具体语法如下:
create function 存储函数名([参数列表])
returns type [characteristic ...]
begin
--SQL语句
return ...;
end;
characteristic:
deterministic: 相同的输入参数总是产生相同的结果
no sql: 不包含SQL语句
reads sql data: 包含读取数据的语句,但不包含写入数据的语句。
# 通过存储函数 完成从1累加到n的值,n为传入的参数值
create FUNCTION fun1(n int)
RETURNS int DETERMINISTIC
BEGIN
DECLARE total int DEFAULT 0;
while n>0 DO
set total := total n;
set n := n - 1;
end while;
RETURN total;
end;
SELECT fun1(100)
触发器是与表结构有关的数据库对象,指在insert/update/delete之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这些特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。
使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其它的数据库是相似的,现在触发器还只支持执行级触发,不支持语句级触发。
insert型的触发器,new表示将要或者已经新增的数据
update型的触发器,OLD表示修改之前的数据,NEW表示将要或已经修改后的数据。
delete型触发器,OLD表示将要或者已经删除的数据。
触发器语法:
# 创建
create TRIGGER 触发器名
before/after insert/UPDATE/DELETE
ON 表名 for each row ... -- 行级触发器
BEGIN
trigger_stmt;
end;
# 查看
SHOW TRIGGER;
# 删除
drop TRIGGER [schema_name] 触发器名; -- 如果没有指定,schema_name,默认为当前数据库
创建一张日志表来监控 king_user的增删改操作,并将更新日志记录到user_logs表中。
create table user_logs(
id int(11) not null auto_increment,
operation varchar(20) not null comment '操作类型 insert/update/delete',
operation_time datetime not null COMMENT '操作时间',
operation_id int(11) not null COMMENT '操作的id',
operation_params VARCHAR(500) COMMENT '操作参数',
primary key(id)
)engine=innodb default charset=utf8;
-- 插入数据时的触发器
create trigger tb_king_user_insert_trigger
AFTER INSERT on king_user for each ROW
BEGIN
insert into user_logs VALUES(null,'insert',now(),new.id,CONCAT('插入的数字内容为: id=',new.id,',name=',new.name,',phone=',new.phone,',email=',new.email,',profession=,',new.profession));
END;
#插入数据测试
mysql> insert into king_user values(12,'卢俊义',38,'男','13298987381','lujunyi@king.com','二当家','2','2021-03-23 12:10:23');
Query OK, 1 row affected (0.04 sec)
mysql> select * from user_logs\G;
*************************** 1. row ***************************
id: 1
operation: insert
operation_time: 2022-04-16 21:26:07
operation_id: 12
operation_params: 插入的数字内容为: id=12,name=卢俊义,phone=13298987381,email=lujunyi@king.com,profession=,二当家
1 row in set (0.01 sec)
ERROR:
No query specified
mysql>
-- 修改数据触发器
create trigger tb_king_user_update_trigger
AFTER update on king_user for each ROW
BEGIN
insert into user_logs VALUES(null,'update',now(),new.id,CONCAT('更新前的数居内容为: id=',old.id,',name=',old.name,',phone=',old.phone,',email=',old.email,',profession=,',old.profession)),
(null,'update',now(),new.id,CONCAT('更新后的数居内容为: id=',new.id,',name=',new.name,',phone=',new.phone,',email=',new.email,',profession=,',new.profession));
END;
UPDATE king_user set age=32 where id=1; # 验证是否记录到日志表里
-- 删除数据触发器
create trigger tb_king_user_delete_trigger
AFTER delete on king_user for each ROW
BEGIN
insert into user_logs VALUES(null,'delete',now(),old.id,CONCAT('删除前的数居内容为: id=',old.id,',name=',old.name,',phone=',old.phone,',email=',old.email,',profession=,',old.profession));
END;
mysql> delete from king_user where id=13;
Query OK, 1 row affected (0.11 sec)
你学费了吗