【数据库——MySQL(实战项目1)】(3)图书借阅系统——存储函数

news2024/11/23 9:17:36

目录

  • 1. 简述
  • 2. 功能代码
    • 2.1 创建存储函数,根据图书编号查借阅人姓名,并调用该函数查询‘ **小邓在森林** ’已借未还的图书情况;
    • 2.2 创建存储函数,计算某借阅人还能借阅的图书数目,学生限额 `5` 本,教师限额 `10` 本。
    • 2.3 创建存储函数,查询某本图书逾期未还的时长,并调用该函数显示所有逾期未归还图书的书名,借阅人和逾期时长并按逾期时长排序;
    • 2.4 创建存储函数,查询某借阅人有几本逾期未还图书,并调用该函数显示有逾期未归还图书的借阅人和未归还图书数目;
    • 2.5 创建存储函数,利用游标计算计算某借阅人逾期未还图书应缴纳的罚款,逾期 `30` 日内罚款 `1` 元,逾期 `90` 日内罚款 `3` 元,逾期超过 `90` 日罚款 `5` 元。调用该函数显示所有应缴纳罚款的借阅人的姓名,逾期罚款和电话;

1. 简述

这篇文章将主要完成图书借阅系统的 4~9 题(存储函数),即:

  1. 创建存储函数,根据图书编号查借阅人姓名,并调用该函数查询‘ 小邓在森林 ’已借未还的图书情况;
  2. 创建存储函数,计算某借阅人还能借阅的图书数目,学生限额 5 本,教师限额 10 本。
  3. 创建存储函数,查询某本图书逾期未还的时长,并调用该函数显示所有逾期未归还图书的书名,借阅人和逾期时长并按逾期时长排序;
  4. 创建存储函数,查询某借阅人有几本逾期未还图书,并调用该函数显示有逾期未归还图书的借阅人和未归还图书数目;
  5. 创建存储函数,利用游标计算计算某借阅人逾期未还图书应缴纳的罚款,逾期 30 日内罚款 1 元,逾期 90 日内罚款 3 元,逾期超过 90 日罚款 5 元。调用该函数显示所有应缴纳罚款的借阅人的姓名,逾期罚款和电话;

2. 功能代码

:若读者并不是从第一篇文章一直到本篇文章执行代码的话(即中途退出了 Navicat),那么需要再次运行下述语句:

# 开启此权限才能创建存储函数(此权限在退出软件后会自动关闭)
set global log_bin_trust_function_creators=TRUE;

2.1 创建存储函数,根据图书编号查借阅人姓名,并调用该函数查询‘ 小邓在森林 ’已借未还的图书情况;

drop FUNCTION if exists f_bookid2borrowername;
delimiter $
create FUNCTION f_bookid2borrowername(bookid char(12))
		returns varchar(20) # 返回借阅人姓名
begin
	declare borrowername varchar(20);
	
	select borrower.`name` into borrowername
	from borrower join information on borrower.id = information.borrowerid
								join book on book.id = information.bookid
	where book.id = bookid and information.returnDateReality IS NULL;
	
	return borrowername;
end$
delimiter ;

检测存储函数是否正确:

set @bookid = 101102512651;
select f_bookid2borrowername(@bookid) as 借阅人姓名;

测试结果如下:

在这里插入图片描述

调用该函数查询‘ 小邓在森林 ’已借未还的图书情况:

# 调用存储函数查询‘小邓在森林’已借未还的图书情况
select book.id as 图书编号, book.`name` as 书名, information.leadDate as 借出日期, information.returnDate as 应还日期, if(TO_DAYS(NOW()) - TO_DAYS(information.returnDate)>=0, TO_DAYS(NOW()) - TO_DAYS(information.returnDate), '未逾期') as '逾期时长(天)',borrower.id as 证件号, borrower.`name` as 姓名
from book join information on book.id = information.bookid
					join borrower on borrower.id = information.borrowerid
where f_bookid2borrowername(book.id) = '小邓在森林' and information.returnDateReality IS NULL;

在这里插入图片描述

:逾期时长是会每天自动增长的,因此读者运行的逾期时长结果可能和我的结果不同~

2.2 创建存储函数,计算某借阅人还能借阅的图书数目,学生限额 5 本,教师限额 10 本。

drop FUNCTION if exists f_ReBorrowTimes;
delimiter $
create FUNCTION f_ReBorrowTimes(borrowerid char(13))
		returns int # 返回还能借阅的图书数目
begin
	declare ReBorrowTimes int;	# 还能借阅的图书数目
	declare Overdue int;				# 已借没还书籍的数量
	
	select COUNT(*) into Overdue
	from borrower join information on borrower.id = information.borrowerid
								join book on book.id = information.bookid
	where returnDateReality IS NULL and borrower.id = borrowerid;

	select if(borrower.category='教师',10 - Overdue, 5 - Overdue) into ReBorrowTimes
	from borrower
	where borrower.id = borrowerid;
	
	return ReBorrowTimes;
end$
delimiter ;

检测存储函数是否正确:

在这里插入图片描述

# 教师(没有未还图书)
set @borrowerid = 1000000000001;
select f_ReBorrowTimes(@borrowerid) as 还能借阅的图书数目;
# 学生(已借未还3本书,只能再借2本书)
set @borrowerid = 2020312011047;
select f_ReBorrowTimes(@borrowerid) as 还能借阅的图书数目;

测试结果如下:

在这里插入图片描述

2.3 创建存储函数,查询某本图书逾期未还的时长,并调用该函数显示所有逾期未归还图书的书名,借阅人和逾期时长并按逾期时长排序;

drop FUNCTION if exists f_OverdueBook;
delimiter $
create FUNCTION f_OverdueBook(bookid char(12))
		returns int # 返回某本图书逾期未还的时长(天)
begin
	declare OverdueTimes int;	# 图书逾期未还的时长(天)
	select TO_DAYS(NOW()) - TO_DAYS(information.returnDate) into OverdueTimes
	from book join information on book.id = information.bookid
						join borrower on borrower.id = information.borrowerid
	WHERE book.id = bookid AND returnDateReality IS NULL AND TO_DAYS(NOW()) - TO_DAYS(information.returnDate) > 0;
	return OverdueTimes;
end$
delimiter ;

检测存储函数是否正确:【此部分检测代码待完成全部功能后再运行

# 逾期图书(即超过了30天未还的图书)
set @bookid = 101102512651;
select if(f_OverdueBook(@bookid) is null, '未逾期', f_OverdueBook(@bookid)) as '图书逾期未还的时长(天)';
# 未逾期图书(即未超过30天未还的图书)
# 先借一本书来测试未逾期图书
call p_InsertLeadInfo(2020312011047,101101699412);
set @bookid = 101101699412;
select if(f_OverdueBook(@bookid) is null, '未逾期', f_OverdueBook(@bookid)) as '图书逾期未还的时长(天)';
# 将图书归还
call p_UpdateLeadInfo(2020312011047,101101699412);
# 在架上图书(未借出图书)
set @bookid = 101101699410;
select if(f_OverdueBook(@bookid) is null, '未逾期', f_OverdueBook(@bookid)) as '图书逾期未还的时长(天)';

测试结果如下:

在这里插入图片描述

:图片虽然没显示还书过程,即 call p_UpdateLeadInfo(2020312011047,101101699412);,但是我另外自己执行了,所以读者就按照我给的代码执行即可,图片只是参考~

调用存储函数显示所有逾期未归还图书的书名,借阅人和逾期时长并按逾期时长排序

select book.`name` as 书名, borrower.id as 证件号, borrower.`name` as 姓名, f_OverdueBook(book.id) as 逾期天数
from book join information on book.id = information.bookid
					join borrower on borrower.id = information.borrowerid
WHERE f_OverdueBook(book.id) IS NOT NULL AND returnDateReality IS NULL
ORDER BY f_OverdueBook(book.id) desc;

在这里插入图片描述

2.4 创建存储函数,查询某借阅人有几本逾期未还图书,并调用该函数显示有逾期未归还图书的借阅人和未归还图书数目;

drop FUNCTION if exists f_OverdueBorrower;
delimiter $
create FUNCTION f_OverdueBorrower(borrowerid char(13))
		returns int # 返回某借阅人逾期未还图书数量
begin
	declare OverdueCount int;	# 逾期未还图书数量
	
	select count(*) into OverdueCount
	from book join information on book.id = information.bookid
						join borrower on borrower.id = information.borrowerid
	WHERE borrower.id = borrowerid AND returnDateReality IS NULL AND TO_DAYS(NOW()) - TO_DAYS(information.returnDate) > 0;
	
	return OverdueCount;
end$
delimiter ;

检测存储函数是否正确:【此部分检测代码待完成全部功能后再运行

# 教师(已借未还且逾期)
set @borrowerid = 1000000000002;
select f_OverdueBorrower(@borrowerid) as '逾期未还图书数(本)';
# 学生(已借未还未逾期)
# 先借一本书来测试未逾期图书
call p_InsertLeadInfo(2018210210205,101101699412);
set @borrowerid = 2018210210205;
select f_OverdueBorrower(@borrowerid) as '逾期未还图书数(本)';
# 将图书归还
call p_UpdateLeadInfo(2018210210205,101101699412);
# 学生(已借未还且逾期)
set @borrowerid = 2020312011047;
select f_OverdueBorrower(@borrowerid) as '逾期未还图书数(本)';
# 学生(未借过书)
set @borrowerid = 2023513266557;
select f_OverdueBorrower(@borrowerid) as '逾期未还图书数(本)';

测试结果如下:

在这里插入图片描述

调用存储函数显示有逾期未归还图书的借阅人和未归还图书数目

select borrower.id as 证件号, borrower.`name` as 姓名, f_OverdueBorrower(borrower.id) as 逾期未还图书数量
from book join information on book.id = information.bookid
					join borrower on borrower.id = information.borrowerid
WHERE f_OverdueBorrower(borrower.id) > 0
GROUP BY borrower.id;

在这里插入图片描述

2.5 创建存储函数,利用游标计算计算某借阅人逾期未还图书应缴纳的罚款,逾期 30 日内罚款 1 元,逾期 90 日内罚款 3 元,逾期超过 90 日罚款 5 元。调用该函数显示所有应缴纳罚款的借阅人的姓名,逾期罚款和电话;

drop FUNCTION if exists f_fine;
delimiter $
create FUNCTION f_fine(borrowerid char(13))
		returns int # 返回某借阅人逾期未还图书数量
begin
	declare fine int DEFAULT(0);	# 逾期总罚款
	declare fine_per int default(0);	# 每本书罚款(临时)
	declare borrower_id char(13);	# 逾期借阅人证件号
	declare OverdueDay int;	# 逾期天数
	declare f int DEFAULT 1;
	
	# 设置游标
	declare c_finesum cursor for
			select borrower.id, TO_DAYS(NOW()) - TO_DAYS(information.returnDate)
			from book join information on book.id = information.bookid
								join borrower on borrower.id = information.borrowerid
			WHERE borrower.id = borrowerid AND returnDateReality IS NULL AND (TO_DAYS(NOW()) - TO_DAYS(information.returnDate)) > 0;
	
	# 错误处理
	declare continue handler for not found
			set f = 0;
	
	open c_finesum;		# 打开游标
		while f = 1 do
				fetch c_finesum into borrower_id, OverdueDay;		# 读取游标
				
				if OverdueDay < 0 then
						set fine_per = 0;
				elseif OverdueDay <= 30 then
						set fine_per = 1;
				elseif OverdueDay <= 90 then
						set fine_per = 3;
				elseif OverdueDay > 90 then
						set fine_per = 5;
				end if;
				
				set fine = fine + fine_per;
		end while;
	close c_finesum;		# 关闭游标
	
	set fine = fine - fine_per;		# 由于continue会导致程序多运行一次,所以要减去最后一次扣多的钱!
	return fine;
end$
delimiter ;

检测存储函数是否正确:【此部分检测代码待完成全部功能后再运行

# 逾期3本书(5+5+5)
set @borrowerid = 2020312011047;
select f_fine(@borrowerid) as '应缴纳的罚款(元)';
# 逾期1本书(5)
set @borrowerid = 1000000000002;
select f_fine(@borrowerid) as '应缴纳的罚款(元)';
# 未逾期
# 先借一本书来测试未逾期图书
call p_InsertLeadInfo(2018210210205,101101699412);
set @borrowerid = 2018210210205;
select f_fine(@borrowerid) as '应缴纳的罚款(元)';
# 将图书归还
call p_UpdateLeadInfo(2018210210205,101101699412);

测试结果如下:

在这里插入图片描述

调用存储函数显示所有应缴纳罚款的借阅人的姓名,逾期罚款和电话(附加邮箱)

select borrower.id as 证件号, borrower.`name` as 姓名, f_fine(borrower.id) as '逾期罚款(元)', borrower.tel as 电话, borrower.email as 邮箱
from borrower
where f_fine(borrower.id) != 0;

在这里插入图片描述

:由于这里的逾期数据每本书都是大于 90 天的,所以都是 5 元往上加,读者可自行修改或者添加数据,来查看不同逾期的罚款情况~

上一篇文章:【数据库——MySQL(实战项目1)】(2)图书借阅系统——数据库测试、视图以及存储过程

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

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

相关文章

两个连续变量乘积线性化——McCormick envelope近似

两个连续变量乘积的形式&#xff0c;可以进行近似线性化转化&#xff08;没有完全等价的线性化方法&#xff09;。要说明的是这是一种近似线性化&#xff0c;并不是完全等价&#xff0c;存在一定的误差。转化的方法是&#xff0c;McCormick envelope近似&#xff08;McCormick …

快速解决“找不到msvcr120.dll无法执行代码”问题,总结5解决方法

计算机已经成为我们生活和工作中不可或缺的一部分。然而&#xff0c;在使用计算机的过程中&#xff0c;我们常常会遇到各种问题&#xff0c;其中之一就是找不到msvcr120.dll文件。这个问题可能会可能导致计算机程序软件&#xff0c;游戏无法正常运行&#xff0c;影响到我们的工…

试图带你一文搞懂transformer注意力机制(Self-Attention)的本质

这篇文章主要想搞懂以下几个问题&#xff1a; 1、什么是自注意力&#xff08;Self-Attention&#xff09; 2、Q,K,V是什么 好了废话不多说&#xff0c;直接进入正题 Q,K,V分别代表query&#xff0c;key和value&#xff0c;这很容易让人联想到python的字典数据结构&#xff…

西安交大转子数据集故障诊断(Python代码,MSCNN结合LSTM结合注意力机制模型)

1.运行效果&#xff1a;西安交大转子数据集故障诊断&#xff08;Python代码&#xff0c;MSCNN结合LSTM结合注意力机制模型&#xff09;_哔哩哔哩_bilibili 2.环境库版本 如果库版本不一样&#xff0c; 一般也可以运行&#xff0c;这里展示我运行时候的库版本&#xff0c;是为了…

多线程 - 锁策略 CAS

常见的锁策略 此处谈到的锁策略,不局限于 Java,C,Python,数据库,操作系统……但凡是涉及到锁,都是可以应用到下列的锁策略的 乐观锁 vs 悲观锁 锁的实现者,预测接下来锁冲突(锁竞争,两个线程针对一个对象加锁,产生阻塞等待了)的概率是大,还是不大,根据这个冲突的概率,来接下…

30+程序员:如何成为工作领域专家丨IDCF

想要独立完成有一定复杂度的开发和维护工作&#xff0c;或者带领团队完成产品发布、项目交付&#xff1f;要成为研发经理、核心项目负责人&#xff1f; 但又苦于没有丰富的实战经验、或是有经验但是没有可以证明能力水平的认证。 在IT行业&#xff0c;年龄是一个敏感话题。特…

AI一体化运维监控方案助力医院监控体系信息化、智能化

智慧医院是现代医疗领域的新兴概念&#xff0c;是通过先进的物联网技术和新兴技术联合人工智能&#xff0c;实现一体化医院运维监控管理&#xff0c;旨在提升医院的安全性、运行效率和服务质量。 具体方案 1、 视频监控系统 医院可以安装视频监控摄像头&#xff0c;覆盖关键区…

vue-mixin

1.vue中&#xff0c;混入(mixin)是一种特殊的使用方式。一个混入对象可以包含任意的组件配置选项(data, props, components, watch,computed…)可以根据需求"封装"一些可复用的单元&#xff0c;并在使用时根据一定的策略合并到组件的选项中&#xff0c;使用时和组件自…

记录使用vant组件库的Popup的问题

使用过程中,需要实现点击遮罩层不关闭,智能点击关闭按钮或提交按钮才能关闭遮罩层,看了官网要使用close-on-click-overlay属性, 一开始的写法是错误的: close-on-click-overlayfalse 这个写法明显传递的是string, 而官网中明确要求要穿布尔值, 所以需要在前面加冒号 :clos…

【基础篇】三、Flink集群角色、系统架构以及作业提交流程

文章目录 1、集群角色2、部署模式3、Flink系统架构3.1 作业管理器&#xff08;JobManager&#xff09;3.2 任务管理器&#xff08;TaskManager&#xff09; 4、独立部署会话模式下的作业提交流程5、Yarn部署的应用模式下作业提交流程 1、集群角色 Flink提交作业和执行任务&…

04在命令行中使用Maven命令创建Maven版的Web工程,并将工程部署到服务器的步骤

创建Maven版的Web工程 使用命令生成Web工程 使用mvn archetype:generate命令生成Web工程时&#xff0c;需要使用一个专门生成Web工程骨架的archetype(参照官网看到它的用法) -D表示后面要附加命令的参数&#xff0c;字母D和后面的参数是紧挨着的&#xff0c;中间没有任何其它…

Mac下通过nvm管理node

背景 本地有两个项目&#xff0c;老项目需要用到node 14&#xff0c;新项目需要用node 16&#xff0c;所以只能通过nvm来管理node了 卸载原始的node 我的node是通过官网的.pkg文件安装的&#xff0c;可以通过以下命令进行删除 sudo rm -rf /usr/local/{bin/{node,npm},lib/…

第四篇Android--TextView使用详解

TextView是View体系中的一员&#xff0c;继承自View&#xff0c;用于在界面中展示文字。 基本用法&#xff1a; <TextViewandroid:id"id/textview"android:layout_width"wrap_content"android:layout_height"wrap_content"android:padding&q…

一文带你上手自动化测试中的PO模式!

在UI的自动化测试中&#xff0c;我们需要把测试使用到的数据分离到文件中&#xff0c;如果单纯的写在我们的测试模块里面&#xff0c;不是一个好的设计&#xff0c;所以不管是什么类型的自动化测试&#xff0c;都是需要把数据分离出来的。当然分离到具体的文件里面&#xff0c;…

Arcgis实现Tiff合并

Arcgis实现Tiff合并 现有四幅Tiff影像 打开数据管理工具 输入使用这四幅影像 下面这个就是建立数据库&#xff0c;这个不对 点击确定 合成完毕

Facebook广告账户被封?最全防封及申诉指南

Facebook广告是海外营销的一大利器&#xff0c;但是随着互联网的发展&#xff0c;有部分不法分子正在利用他进行盈利&#xff0c;导致Facebook官方安全审核日益严格&#xff0c;不少卖家遭遇封号问题&#xff01;这篇文章就来教你如何更好地管理 Facebook广告帐户&#xff0c;实…

精品Python的美食推荐系统厨房点餐订餐

《[含文档PPT源码等]精品Python的美食推荐系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#xff1a;JavaScript、VUE.…

大模型增长时代!低代码和 AI 的能力远不止 APP 开发

从低代码开发引发效率革命&#xff0c;到生成式 AI 打破传统限制、颠覆想象&#xff0c;一个前所未有的创造力时代已然开启。作为这场技术变革的见证者和参与者&#xff0c;让创新技术真正“为己所用”&#xff0c;解锁更多的潜在应用场景和机会&#xff0c;无疑是我们共同的目…

es6(二)——常用es6说明

ES6的系列文章目录 es6&#xff08;一&#xff09;——var和let和const的区别 文章目录 ES6的系列文章目录一、变量的结构赋值1.数组的结构赋值2.对象的结构赋值 二、模板字符串三、扩展运算符1.字符串的使用2.数组的使用 四、箭头函数1.普通函数的定义2.箭头函数的定义3.箭头…

大数据时代精准营销是提升品牌竞争力的核心

在营销理论基石渐被撼动和数字时代逐渐兴起的环境下&#xff0c;基于大众市场和大众消费的传统营销理论和方式在受众裂变(碎片化与再中心化)的现实中遇到了瓶颈&#xff0c;传统营销理念和方式在寻找目标受众的过程中已失去了威力。在数字化环境下&#xff0c;如何更好、更精准…