第13章:存储过程和存储函数

news2024/11/28 14:39:07

一、存储过程

1.1理解

含义:

存储过程stored procedure,思想是一组经过预先编译的SQL语句的封装。

存储过程预先存储在MySQL服务器上,需要执行的时候,客户端向服务器端发出调用存储过程的命令,服务器段把这组SQL执行。

好处:

①简化操作,提高sql语句的重用性。

②减少操作过程中的失误,提高效率

③减少网络传输量,因为客户端不需要把所有的SQL语句通过网络发给服务器

④减少SQL语句网上暴露的风险,提高数据查询的安全性

使用

存储过程直接操作底层数据库,存储过程创建出来后,直接调用存储过程名就可以,存储过程没有返回值。

1.2分类

①没有参数:无参数无返回

②in类型:有参数无返回

③out类型:无参数有返回

④inout类型:有参数有返回

⑤in类型和out类型:有参数有返回

2.创建存储过程

2.1语法分析

 2.2设置新的结束标记

delimiter 新的结束标记

说明

MySQL默认结束是分号’;’,为了避免冲突,需要用delimiter设置新的结束标记。

举例

delimiter $ #结束标志是$
create procedure 存储过程名字()
begin
SQL语句;
end $ 
delimiter ; #改为结束标志是;

2.3代码实现

举例1:创建存储过程select_all_data(),查看 emps 表的所有数据

delimiter $
create procedure select_all_data()
begin
select * from emps;
end $
delimiter ;

调用

call select_all_data();

举例2:创建存储过程avg_employee_salary(),返回所有员工的平均工资

delimiter $
create procedure avg_employee_salary()
begin 
select avg(salary) avg_employee_salary
from emps
end $
delimiter ;

举例3:创建存储过程show_max_salary(),用来查看“emps”表的最高薪资值。

delimiter $
create procedure show_max_salary()
begin 
select max(salary) from emps;
end $
delimiter ;

举例4:创建存储过程show_min_salary(),查看“emps”表的最低薪资值。并将最低薪资通过OUT参数“ms”输出

delimiter $
create procedure show_min_salary(out ms double)
begin 
select min(salary) into ms
from emps;
end $
delimiter ;

调用

call show_min_salary(@ms);

select @ms;

举例5:创建存储过程show_someone_salary(),查看“emps”表的某个员工的薪资,并用IN参数empname输入员工姓名。

delimiter $
create procedure show_someone_salary(in ename varchar(25))
begin 
select salary
from emps
where last_name=ename;
end $
delimiter ;

调用

call show_someone_salary('Abel')

举例6:创建存储过程show_someone_salary2(),查看“emps”表的某个员工的薪资,并用IN参数empname输入员工姓名,用OUT参数empsalary输出员工薪资。

delimiter $
create procedure show_someone_salary2(in ename varchar(20),out ms double)
begin 
select salary into ms 
from emps 
where last_name=ename;
end $
delimiter ;

调用

set @ename=’Abel’;

call show_someone_salary2(@ename,@ms);

select @ms;

举例7:创建存储过程show_mgr_name(),查询某个员工领导的姓名,并用INOUT参数“empname”输入员工姓名,输出领导的姓名。

delimiter $
create procedure show_mgr_name1(inout ename varchar(20))
begin
select last_name into ename
from emps 
where employee_id = (
select manager_id
from emps
where last_name = ename
);
end $
delimiter ;

调用

set @ename='Abel';

call show_mgr_name1(@ename);

select @ename;

2.4 调用格式

①调用in模式的参数:

call 存储过程名(‘值’)

②调用out模式的参数:

set @name;

call 存储过程名(@name);

select @name;

③调用inout模式的参数:

set @name=值;

call 存储过程名(@name);

select @name;

二、存储函数

1.语法分析

 创建存储函数报错you might want to use the less safe log_bin_trust_function_creators variable的方法:

①加上函数特性deterministic(确定)

和contains sql(包含sql)|no sql(不包含sql)|reads sql data (读sql数据)|modifies sql data(改sql数据)

mysql> SET GLOBAL log_bin_trust_function_creators = 1;

2.调用函数

select 函数名(实参列表)

3.代码举例

举例1:

创建存储函数,名称为email_by_name(),参数定义为空,该函数查询Abel的email,并返回,数据类型为字符串型。

delimiter $
create function email_by_name()
returns varchar(25) # 返回类型
deterministic # 确定的
contains sql # 包含sql
reads sql data  # 读sql
begin 
	return(
	select email from emps where last_name='Abel'
		  );
end $
delimiter ;

调用select email_by_name();

举例2:

创建存储函数,名称为email_by_id(),参数传入emp_id,该函数查询emp_id的email,并返回,数据类型为字符串型。

delimiter $
create function email_by_id(emp_id int)
returns varchar(25)
begin
 return (select email from emps where employee_id=emp_id);
end $
delimiter ;

 调用

set @id = 101;

select email_by_id(@id)

举例3

创建存储函数count_by_id(),参数传入dept_id,该函数查询dept_id部门的员工人数,并返回,数据类型为整型。

delimiter $
create function count_by_id(depid int)
returns int
begin 
return (
select count(*)
from emps 
where department_id = depid
);
end $
delimiter ;

调用

select count_by_id(80)

4.对比存储函数和存储过程

存储函数可以在查询语句中使用,存储过程不可以。存储过程的功能更加强大,可以对表的操作和事务操作。

三、存储过程和函数的查看、修改、删除

查看

1.查看存储过程和存储函数的创建信息

show create procedure|function 名称

2.使用show status 语句查看存储过程和函数的状态信息

show procedure status like 'show_max_salary'

show function status

3.从information_schema.Routines表中查询存储过程和函数的信息

select *

from information_schema.ROUTINES

where ROUTINE_NAME='count_by_id'

修改

1.只是修改特性,不影响功能

 2.举例

举例1

修改存储过程CountProc的定义。将读写权限改为MODIFIES SQL DATA,并指明调用者可以执行,代码如下:

alter procedure CountProc
modifies sql data
sql security invoker;

 结果:

select *
from information_schema.ROUTINES
where ROUTINE_NAME='CountProc '

 举例2

修改存储函数CountProc的定义。将读写权限改为READS SQL DATA,并加上注释信息“FIND NAME”,代码如下:

alter function CountProc
reads sql data 
comment ‘FIND NAME’

 删除

drop procedure|function 名字

四、存储过程阿里开发规范

禁止使用存储过程,难以调试和扩展,没有移植性。经典白学啊哈哈哈~

五、练习

存储过程

#0.准备工作

CREATE DATABASE test15_pro_func;

USE test15_pro_func;

#1. 创建存储过程insert_user(),实现传入用户名和密码,插入到admin表中

CREATE TABLE admin(

id INT PRIMARY KEY AUTO_INCREMENT,

user_name VARCHAR(15) NOT NULL,

pwd VARCHAR(25) NOT NULL

);

delimiter $
create procedure insert_user(in name varchar(15),in pwd varchar(25))
begin 
insert into admin(user_name,pwd)
values (name,pwd);
end $
delimiter ;

测试

call insert_user('wang','1234')

#2. 创建存储过程get_phone(),实现传入女神编号,返回女神姓名和女神电话

CREATE TABLE beauty(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(15) NOT NULL,

phone VARCHAR(15) UNIQUE,

birth DATE

);

INSERT INTO beauty(NAME,phone,birth)

VALUES

('朱茵','13201233453','1982-02-12'),

('孙燕姿','13501233653','1980-12-09'),

('田馥甄','13651238755','1983-08-21'),

('邓紫棋','17843283452','1991-11-12'),

('刘若英','18635575464','1989-05-18'),

('杨超越','13761238755','1994-05-11');

SELECT * FROM beauty;

delimiter $
create procedure get_phone2(in id int,out name varchar(15),out phone varchar(15))
begin 
select b.name,b.phone into name,phone
from beauty b
where b.id=id;
end $
delimiter ;

测试

call get_phone2(1,@name,@phone);

select @name,@phone;

#3. 创建存储过程date_diff(),实现传入两个女神生日,返回日期间隔大小

delimiter $
create procedure date_diff(in date1 date,in date2 date)
begin
 select DATEDIFF(date1,date2) from dual;
end $
delimiter ;

测试

call date_diff2('1999-03-22','1994-08-19')

#4. 创建存储过程format_date(),实现传入一个日期,格式化成xxxxxx日并返回

delimiter $
create procedure format_date(in date date)
begin 
select concat(YEAR(date),'年',MONTH(date),'月',DAY(date),'日') from dual;
#或SELECT DATE_FORMAT(mydate,'%y年%m月%d日')from dual;
end $
delimiter ;

测试

call format_date('2022-5-4')

#5. 创建存储过程beauty_limit(),根据传入的起始索引和条目数,查询女神表的记录

delimiter $
create procedure beauty_limit(in pageNo int,in pageSize int)
begin
 select id,name,phone,birth
 from beauty
 limit pageNo,pageSize;
end $
delimiter ; 

测试

call beauty_limit(0,5)

#创建带inout模式参数的存储过程

#6. 传入ab两个值,最终ab都翻倍并返回

delimiter $
create procedure retdouble(inout a int,inout b int)
begin 
set a=a*2;
set b=b*2;
end $
delimiter ;

调用

set @a=2,@b=5;

call retdouble(@a,@b);

select @a,@b

#7. 删除题目5的存储过程

 drop procedure beauty_limit

show procedure status

#8. 查看题目6中存储过程的信息

show create procedure 'retdouble';

show procedure status like 'retdouble';

存储函数

#0. 准备工作

USE test15_pro_func;

CREATE TABLE employees

AS

SELECT * FROM atguigudb.`employees`;

CREATE TABLE departments

AS

SELECT * FROM atguigudb.`departments`;

#无参有返回

#1. 创建函数get_count(),返回公司的员工个数

delimiter $
create function get_count()
returns int
begin
 return (select count(*) from employees);
end $
delimiter ;

测试

select  get_count()

#有参有返回

#2. 创建函数ename_salary(),根据员工姓名,返回它的工资

delimiter $
create function ename_salary(ename varchar(25))
returns double 
begin 
return (select salary from employees where last_name=ename);
end $
delimiter ;

测试

select ename_salary('Abel');

#3. 创建函数dept_sal() ,根据部门名,返回该部门的平均工资

delimiter $
create function dept_sal1(dname varchar(20))
returns double
begin 
return (
select avg(salary)
from employees e
join departments d on e.department_id=d.department_id
where d.department_name=dname
);
end $
delimiter ;

调用

SELECT dept_sal1('Marketing');

#4. 创建函数add_float(),实现传入两个float,返回二者之和

delimiter $
create function add_float(a float,b float)
returns float 
begin
return (select a+b from dual); 
end $
delimiter ;

调用

select add_float(2,3);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/537603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

当我和ChatGPT-4聊完后,我觉得一切可能已经来不及了

飞机上有wifi,了然无味,在万米高空,和ChatGPT-4开始了一场坦诚的沟通,它全程都表现出高情商,以及不断尽量安抚我的情绪,而这,恰恰令我脊背发凉。 部分文字截取 ZM:我能不能理解每次对…

k8s学习-CKS真题-ImagePolicyWebhook容器镜像扫描

目录 题目环境搭建imagePolicyWebhook搭建 解题任务二任务三任务一检查 模拟考题参考 题目 Context cluster上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。 完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。 Task 注意&#xff…

5.17 ARM 作业

1. 2.用for循环实现1~100之间的和 13BA 3.xmind

可以找工作的C端的低代码产品,终于让我找到了

目录 写在前面 低代码平台 平台怎么选 各平台区别 为什么选它 写在前面 大家都知道低代码这个叫法是从B端叫起来的,也就是说不管是业务人员还是开发人员,都是企业内部使用。那么有没有C端的,且免费使用的低代码产品呢? 低代码…

一次性能优化思考过程

前言 最近业务上空闲了下来,也是把之前在开发时自身感受比较大的白屏时间放在了主线上去排查优化,这里记录一下笔者对于移动端vConsole脚本的引入问题全过程。 网络脚本与问题定位 对于白屏时间,与网络传输有很大关系,如图&…

该怎样学习网络安全知识?

首先,必须(时刻)意识到你是在学习一门可以说是最难的课程,是网络专业领域的顶尖课程,不是什么人、随随便便就能学好的。不然,大家都是黑客,也就没有黑客和网络安全的概念了。 很多朋友抱着学一…

#systemverilog# 之 event region 和 timeslot 仿真调度(五)实战

目录 一 问题代码 二 解决方法 2.1 调换代码顺序 2.2 #0 Delay 2.3 uvm class 执行移到re-avtive 2.4 搭建完备的UVM 验证平台 三 预期波形 经过之前文章的学习,想必大家对systemverilog 仿真调度的理解,应该八九不离十了。今天,我们…

基于STM32的NRF24L01 2.4G通讯模块的驱动实验(HAL库)

前言:本文为手把手教学NRF24L01 2.4G通讯模块的驱动实验,本教程的 MCU 采用STM32F103ZET6与STM32F103C8T6,彼此进行互相通讯。通过 CubeMX 软件配置 SPI 协议驱动NRF24L01 2.4G通讯模块(HAL库)。NRF24L01 2.4G是嵌入式…

渗透测试--5.2.hash密码的破解

目录 1.hashcat简介 2.hashcat参数 常见参数 哈希类型(-m) 破解模式(-a) 3.实例 步骤一:使用hash-identifier工具判断哈希值类型 步骤二:使用字典攻击进行破解 1.hashcat简介 hashcat号称世界上最…

js实现点击改变文字大小

目录 一、前言二、代码实现 一、前言 在编写代码之前我们先来看看通过js获取元素有几种方式&#xff1a; 1.第一种 document.querySelector() 返回文档中匹配指定的选择器组的第一个元素document.querySelectorAll(); 返回文档中匹配指定的选择器组的所有元素 <!DOCTYPE ht…

vector容器 [上]

目录 一、 对于vector的介绍 二、vector的定义 0x01 无参构造 0x02 构造并初始化n个val 0x03 使用迭代器进行初始化构造 0x04 拷贝构造 0x05 比较 三、 vector的遍历 0x01 push_back() 0x02 operator[] 和at() 0x03 遍历 四、vector 容量空间 0x01 max_size : 返回v…

【设置教程】未使用系统分配DNS地址 如何设置?答:

未使用系统分配DNS地址&#xff0c;是你的域名解析DNS地址不是当前系统的DNS地址。 设置方法&#xff1a;先关闭更新。域名控制台--域名列表--安全设置&#xff1a; 通过短信验证。 2、修改DNS地址&#xff1a;域名控制台--域名列表&#xff1a;点击域名&#xff1a; 3、点击&…

C语言函数速查

scanf函数 函数概要&#xff1a; scanf 函数从标准输入流中读取格式化字符串。 与 printf 格式化输出函数相反&#xff0c;scanf 函数是格式化输入函数。 函数原型&#xff1a; #include <stdio.h> ... int scanf(const char *format, ...);参数解析&#xff1a; 1…

事务 ---MySQL的总结(六)

事务 多进程进行并改变同一个数据&#xff0c;如果没有进行版本控制&#xff0c;就会出现数据不确定的问题&#xff0c;为此引入了事务的概念。可以进行数据回滚&#xff0c;解决潜在的问题。 事务的概念 一组的DML组成&#xff0c;这一些的DML要么同时成功&#xff0c;要么同…

Linux上开启coredump

Linux上开启core dump Core dump&#xff08;核心转储&#xff09;是在程序崩溃时生成的一种文件&#xff0c;其中包含了程序在崩溃时的内存状态信息。它可以帮助程序员在调试程序时快速定位问题&#xff0c;并且是一种非常有用的调试工具。core dump的作用如下&#xff1a; 帮…

Java面向对象程序设计实验报告(实验二 面向对象基础练习)

✨作者&#xff1a;命运之光 ✨ 专栏&#xff1a;Java面向对象程序设计实验报告 目录 ✨一、需求设计 ✨二、概要设计 ✨三、详细设计 ✨四、调试结果 ✨五、测试结果 ✨附录&#xff1a;源程序代码&#xff08;带注释&#xff09; 测试类demo2 Address类 Employee类…

Docker之DockerFile相关基础知识

DockerFile相关基础知识 一、Docker镜像原理1、操作系统组成部分1.1 七大子系统1.2 Linux文件系统 2、Docker镜像原理介绍2.1 原理图2.2 Docker镜像本质2.3 统一文件系统2.4 复用性2.5 统一性 二、容器转为镜像1、Docker镜像的制作1.1 容器转换为镜像1.2 镜像转为压缩文件1.3 导…

【SpringBoot】三:访问数据库

文章目录 1.DataSource2.JdbcTemplate2.1 准备环境2.2 准备表和数据2.3 配置数据源2.4 JdbcTemplate访问mysql2.5 创建实体类 ArticlePO2.6 测试2.6.1 测试聚合函数 3.mybatis3.1 单表CRUMD3.1.1 创建模块3.1.2 查询3.1.3 插入3.1.4 更新3.1.5 删除 3.2 ResultMap3.3 SQL 提供者…

Elasticsearch 集群部署管理

Elasticsearch 集群配置版本均为8以上 安装前准备 CPU 2C 内存4G或更多 操作系统: Ubuntu20.04,Ubuntu18.04,Rocky8.X,Centos 7.X 操作系统盘50G 主机名设置规则为nodeX.qingtong.org 生产环境建议准备单独的数据磁盘主机名 #各自服务器配置自己的主机名 hostnamectl set-ho…

【2023/05/17】smalltalk

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第12天。 Share His own morning are new surprises to God. 译文&#xff1a; 神自己的清晨&#xff0c;在他自己看来也是新奇的。 Life finds its wealth by the claims of the world,and its worth…