16_MySQL中的存储过程和触发器
文章目录
- 1. 存储过程和函数
- 1.1 存储过程和函数概述
- 1.2 创建存储过程
- 1.3 调用存储过程
- 1.4 查看存储过程
- 1.5 删除存储过程
- 1.6 存储过程示例:
- 1.6.1 空参
- 1.6.2 带in
- 1.6.3 带out
- 1.6.4 带inout
- 2. 触发器
- 2.1 介绍
- 2.2 创建触发器
- 2.3 删除触发器
- 2.4 查看触发器
1. 存储过程和函数
1.1 存储过程和函数概述
存储过程和函数是 事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
即可以在数据库中书写存储过程与函数,使用JDBC时就可以直接调用这俩者,而不用再使用一条条的SQL语句增加服务器与数据库 的传输
存储过程和函数的区别在于函数必须有返回值,而存储过程没有。
函数 : 是一个有返回值的过程 ;
过程 : 是一个没有返回值的函数 ;
存储过程的使用会比函数更多
1.2 创建存储过程
CREATE PROCEDURE 存储过程名 ([参数列表])
begin-- SQL语句
end ;
-- begin和end就相当于Java的俩个大括号
示例 :
delimiter $create procedure pro_test1()
beginselect 'Hello Mysql' ;
end$delimiter ;
知识小贴士
DELIMITER
该关键字用来声明SQL语句的分隔符 , 告诉 MySQL 解释器,该段命令是否已经结束了,mysql是否可以执行了。默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。
所以在书写存储过程时需要先将分隔符修改,存储过程结束了再将分隔符修改回来
注意:
参数列表包含三部分,参数模式 参数名 参数类型
其中参数名 参数类型与函数一致,顺序与java相反
而参数模式是由MySQL系统规定的三种模式,它们分别是:
- in:该参数可以作为输入,也就是该参数需要调用方传入值
- out:该参数可以作为输出,也就是该参数可以作为返回值
- inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值
如果存储过程体仅仅只有一句话,begin end可以省略
存储过程体中的每条sql语句的结尾要求必须加分号。
存储过程的结尾可以使用 delimiter 重新设置。SQL语句最好以分号结尾,但定义存储过程前如果不设置新的SQL语句结尾,那编译存储过程时可能因为遇见分号直接运行了
1.3 调用存储过程
采用call关键字,语法如下:
call procedure_name() ;
1.4 查看存储过程
-- 查询db_name数据库中的所有的存储过程
-- 从mysql数据库中的proc表中查找
-- mysql这个库中的proc表存放了所有的存储过程
select name from mysql.proc
where db='db_name';-- 查询存储过程的状态信息
show procedure status;-- 不能使用DESC 存储过程名来查看存储过程的结构-- 查询某个存储过程的定义,即创建语句
-- \G是在命令行窗口中将查询信息竖着展示
show create procedure test.pro_test1 \G;
1.5 删除存储过程
DROP PROCEDURE [IF EXISTS] 存储过程名 ;
注意:不能在一条语句中删除多个存储过程
1.6 存储过程示例:
1.6.1 空参
-- 示例1:插入到admin表中五条记录
DELIMITER $# 指定结束标记
CREATE PROCEDURE mypro1()# 空参
BEGIN# 相当于Java方法中大括号{}INSERT INTO admin(username,password) VALUES('zs1','123456'),('zs2','123456'),('zs3','123456'),('zs4','123456'),('zs5','123456');
END $# 因为在存储过程体中每条SQL语句使用了分号结束语句,但存储过程什么时候结束系统并不知道,所以需要在END后面插入一个结束标记表示该存储过程已经完了CALL mypro1()$ # 调用存储过程,注意:在调用的时候如果是在Navicat For MySQL软件上那么结束标记要写分号";",否则报错,如果是在漆黑的DOS窗口中,那么就要使用定义的结束标记"$"否则不会结束
DELIMITER ;# 为了符合平时的习惯,还是改回来在创建存储过程完成后
1.6.2 带in
-- 示例1:创建存储过程实现,根据女神名,查询对应的男神信息
DELIMITER $# 指定结束标记,由于我们恢复了分号的结束标记,所以需要重新设置
CREATE PROCEDURE mypro2(IN beautyName VARCHAR(20))# 第一个IN表示该参数是IN模式,beautyName是参数名称,VARCHAR(20)是参数类型
BEGINSELECT *FROM boys boRIGHT JOIN beauty b ON bo.id=b.boyfriend_idWHERE b.name=beautyName;
END $CALL mypro2()$
DELIMITER ;# 为了符合平时的习惯,还是改回来在创建存储过程完成后
俩个in:
-- 示例2:创建存储过程实现,用户是否登录成功
DELIMITER $# 指定结束标记,由于我们恢复了分号的结束标记,所以需要重新设置
CREATE PROCEDURE mypro3(IN username VARCHAR(20),IN password VARCHAR(20))
BEGINDECLARE result INT DEFAULT 0;# 声明一个用户变量来保存查询结果SELECT COUNT(*) INTO result# 赋值FROM adminWHERE admin.username=username# 如果重名,那么用表名进行区分AND admin.password=password;SELECT IF(result>0,'成功','失败');# 使用
END $CALL mypro3()$# 调用存储过程
DELIMITER ;# 为了符合平时的习惯,还是改回来在创建存储过程完成后
1.6.3 带out
-- 示例1:根据输入的女神名,返回对应的男神名
DELIMITER $# 指定结束标记,由于我们恢复了分号的结束标记,所以需要重新设置
CREATE PROCEDURE mypro4(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))
BEGINSELECT bo.boyname INTO boyName#赋值FROM boys boRIGHT JOINbeauty b ON b.boyfriend_id=bo.idWHERE b.name=beautyName;
END$# 相当于原来分号作为结束标记,其实没必要空格的DELIMITER ;# 这里先将结束标记设置回来,下面就可以直接使用分号作为结束标记了
SET @boyName='';# 创建一个用户变量来存储返回值
CALL mypro4('小昭',@boyName);# 调用存储过程,传入两个参数
SELECT @boyName;# 调用已经被赋值了的用户变量
1.6.4 带inout
-- 示例1:传入a和b两个值,最终a和b都翻倍并返回
# 创建存储过程
DELIMITER $ -- 指定结束标记,由于我们恢复了分号的结束标记,所以需要重新设置
CREATE PROCEDURE mypro5(INOUT a INT,INOUT b INT)
BEGINSET a=a*2;SET b=b*2;
END$# 调用存储过程
DELIMITER ; -- 这里先将结束标记设置回来,下面就可以直接使用分号作为结束标记了
SET @m=10; -- 创建两个用户变量作为INOUT模式的参数
SET @n=20;
CALL mypro5(@m,@n);
SELECT @m,@n;
2. 触发器
2.1 介绍
触发器是与表有关的数据库对象,指在 insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作 。
触发器是一种特殊的存储过程,只有DELTE、INSERT、UPDATE这三种语句能够支持触发器,其他的SQL语句不支持。
在触发器中有俩个行记录变量OLD和NEW
使用别名 OLD 和 NEW 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。
触发器类型 | NEW 和 OLD的使用 |
---|---|
INSERT 型触发器 | NEW 表示将要或者已经新增的数据 |
UPDATE 型触发器 | OLD 表示修改之前的数据 , NEW 表示将要或已经修改后的数据 |
DELETE 型触发器 | OLD 表示将要或者已经删除的数据 |
可以通过old/new.操作表的列名获取操作表的这一行时对应的数据
2.2 创建触发器
语法结构 :
create trigger trigger_name before/after insert/update/deleteon tbl_name [ for each row ] -- 表明是行级触发器
-- 因为mysql只支持行级触发器,所以以上必写begintrigger_stmt ; -- SQL语句end;
示例
需求
通过触发器记录 emp 表的数据变更日志 , 包含增加, 修改 , 删除 ;
首先创建一张日志表 :
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 '操作时间',-- 可以通过now()函数获取operate_id int(11) not null comment '操作表的ID',-- 通过NEW.id获取operate_params varchar(500) comment '操作参数',primary key(`id`)
)engine=innodb default charset=utf8;
创建 insert 型触发器,完成插入数据时的日志记录 :
DELIMITER $create trigger emp_logs_insert_trigger
after insert
on emp
for each row
begininsert 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 $DELIMITER ;
创建 update 型触发器,完成更新数据时的日志记录 :
DELIMITER $create trigger emp_logs_update_trigger
after update
on emp
for each row
begininsert into emp_logs (id,operation,operate_time,operate_id,operate_params) values(null,'update',now(),new.id,concat('修改前(id:',old.id,', name:',old.name,', age:',old.age,', salary:',old.salary,') , 修改后(id',new.id, 'name:',new.name,', age:',new.age,', salary:',new.salary,')'));
end $DELIMITER ;
创建delete 行的触发器 , 完成删除数据时的日志记录 :
DELIMITER $create trigger emp_logs_delete_trigger
after delete
on emp
for each row
begininsert 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 $DELIMITER ;
测试:
insert into emp(id,name,age,salary) values(null, '光明左使',30,3500);
insert into emp(id,name,age,salary) values(null, '光明右使',33,3200);update emp set age = 39 where id = 3;delete from emp where id = 5;
2.3 删除触发器
语法结构 :
drop trigger [schema_name.]trigger_name
如果没有指定 schema_name,默认为当前数据库 。
2.4 查看触发器
可以通过执行 SHOW TRIGGERS 命令查看触发器的状态、语法等信息。
语法结构 :
show triggers;
16_MySQL中的存储过程和触发器相关推荐
- mysql在触发器中调用存储过程_mysql 触发器中调用存储过程
想要在MYSQL的触发器中调用存储过程,但是IDE提示: 0A000 Not allowed to return a result set from a trigger 触发器代码如下: DELIMI ...
- 数据库原理与应用(SQL Server)笔记 第九章 存储过程和触发器
目录 前言 一.存储过程 (一)存储过程的定义 (二)存储过程的特点 (三)存储过程的分类 1.用户存储过程 2.系统存储过程 3.扩展存储过程 (四)存储过程的创建 (五)存储过程的执行 (六)带参 ...
- SQL 2005 的存储过程和触发器调试大法
SQL 2005 的存储过程和触发器调试大法(原创) 在SQL2000中,我们想要调试存储过程非常简单,只需要在对象浏览器中找到存储过程,然后点击鼠标右键选择"执行(调试)&q ...
- 什么是存储过程?什么是触发器?SQL中存储过程与触发器的区别是什么?
什么是存储过程?什么是触发器?SQL中存储过程与触发器的区别是什么? 存储过程是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名 ...
- 一条SQL语句查询数据库中的所有表、存储过程、触发器
一条SQL语句查询数据库中的所有表.存储过程.触发器 (sysobjects表信息) 该条语句查询返回所有的用户表 select * from sysobjects where xtype='u' ...
- Oracle中通过Function,存储过程,触发器,调用实现解析Clob字段中存在的xml字符串...
摘要:接着之前的问题,在Oracle数据库中通过Function,存储过程,触发器实现解析数据表中CLOB大数据字段中存在的xml字符串有时,有个特殊的时间字符串要在数据库格式化处理,之前解析过来的时 ...
- mysql触发器调用存储过程出错_mysql 触发器中调用存储过程
想要在MYSQL的触发器中调用存储过程,但是IDE提示: 0A000 Not allowed to return a result set from a trigger 触发器代码如下: DELIMI ...
- 数据库中存储过程和触发器的区别是什么
今天给大家分享的是数据库中存储过程和触发器的区别是什么,很多人都不太了解,今天为了让大家更加了解数据库中存储过程和触发器的区别,所以给大家总结了以下内容,一起往下看吧.一定会有所收获的哦. 存储过程和 ...
- 获取MSSQL Server中的相关信息(视图、存储过程、触发器、表)
在SQL SERVER得到某个数据库下面所有的表.视图.存储过程.触发器 select name from sysobjects where xtype='TR' --所有触发器 select nam ...
最新文章
- 苹果首任AI总监Ruslan Salakhutdinov:如何应对深度学习的两大挑战?(附视频)
- php 判断类存在,PHP怎么判断类是否存在
- java11正式发布了,让java代码更完美
- oracle先删后建,oracle 建表之前先删除语句
- idea maven打包_20201116(Maven学习)
- 学习KMP (概念 + 模板 + 例题: 子串查找)
- 米的建站日记(2014年12月15日)
- node学习笔记,第一个Node程序
- 微博粉丝平台开发全攻略
- PBR理论基础3:基于图像的光照(上)
- 选个关注热度上升的大数据工具学习下吧
- 码云 注册 注册个性域名报错---已经解决
- 韦小宝丝绸|如何鉴别香云纱可以用以下六种方法
- 《青山翠影》玖 独行的时代 | 去程归程
- 拼多多稽查系统升级,现在还有3个稳定出评
- 【Android】Android中如何取消调转界面后EditText默认获取聚焦问题
- 解决方案Solution
- 大学计算机基础 一 实验报告,《大学计算机基础》实验报告实验一.docx
- 中国医科大学22春《计算机基础与应用 》在线作业【标准答案】
- 新库上线 | CnOpenDataA股上市公司董监高信息数据
热门文章
- 华为设备的交换机接口类型介绍及配置
- ROS:古月居第一次作业(话题与服务编程、动作编程、TF编程)
- tf卡加卡套的区别_SD卡与TF的区别
- java三种移位运算符
- 百度高级科学家——王海峰
- java 正则表达式 大括号_正则表达式:小括号、中括号、大括号的区别
- 计算机服务选项卡在哪里,常规选项卡在哪_电脑上的“常规”选项卡在什么地方啊?...
- 同盾科技牵头制定标准,推动数据安全在金融领域应用
- SpringBoot集成JWT(极简版)
- 中国石油大学《安全行为学》第一阶段在线作业