MYSQL实训七——存储过程、函数与触发器

2023-10-31

第1关:创建存储过程

任务描述

本关任务:创建存储过程 pro_findname 对学生姓名进行模糊查找,输入任一字输出姓名中含有该字的全部学生。

相关知识

为了完成本关任务,你需要掌握: 1.存储过程的定义; 2.存储过程的创建和查询; 3.存储过程的查询和删除。

存储过程的定义

存储过程Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

简单的说存储过程就是具有名字的一段代码,用来完成一个特定的功能。

存储过程的创建和查询

创建存储过程:create procedure 存储过程名(参数)

  • 下面我们来创建第一个存储过程

每个存储的程序都包含一个由 SQL 语句组成的主体。此语句可能是由以分号(;)字符分隔的多个语句组成的复合语句。例如:

 
  1. CREATE PROCEDURE proc1()
  2. BEGIN
  3. SELECT * FROM user;
  4. END;
  • 执行存储过程:call 存储过程名

  • 创建带有参数的存储过程 存储过程的参数有三种:

    • IN:输入参数,也是默认模式,表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回;
    • OUT:输出参数,该值可在存储过程内部被改变,并可返回;
    • INOUT:输入输出参数,调用时指定,并且可被改变和返回。

存储过程的查询和删除

我们如何在数据库中查询我们已经创建过的存储过程呢:

 
  1. SHOW PROCEDURE STATUS WHERE db='数据库名';

查看存储过程的详细定义信息:

 
  1. SHOW CREATE PROCEDURE 数据库.存储过程名;

当我们不再需要某个存储过程时,我们可以使用:

 
  1. DROP PROCEDURE [IF EXISTS] 数据库名.存储过程名;

编程要求

根据提示,在右侧编辑器补充代码,创建存储过程pro_findname 对学生姓名进行模糊查找,输入任一字输出姓名中含有该字的全部学生。

测试说明

平台会对你编写的代码进行测试,将调用你编写的存储过程:call pro_findname('明'),具体输出请参考右侧测试集。

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
 delimiter $$
    create procedure pro_findname(in name char(3))
  Begin
  select * from student where sname like concat('%',name,'%');

  End $$
  delimiter ;
 /**********End**********/


第2关:创建函数-count_credit

任务描述

本关任务:设计函数 count_credit,根据学号计算该学生的总学分,只有当成绩大于等于60分时才能获得该门课程的学分。

相关知识

为了完成本关任务,你需要掌握:

  1. mysql 自定义函数的定义;
  2. 自定义函数如何创建。

自定义函数的定义

  • 自定义函数是一种过程式数据库对象,与存储过程十分相似的。是由 SQL 语句和过程式语句组成的代码片段。

自定义函数的创建

语法如下:

CREATE FUNCTION <函数名> ( [ <参数1> <类型1> [ , <参数2> <类型2>] ] … ) RETURNS <类型> <函数主体>

编程要求

根据提示,在右侧编辑器补充代码,设计函数 count_credit,根据学号计算该学生的总学分,只有当成绩大于等于60分时才能获得该门课程的学分。

测试说明

平台会对你编写的代码进行测试:本题中该学生选“马蓉”,学号为“97001”)

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
 delimiter $$

  CREATE FUNCTION count_credit(stuno char(6)) returns int

  reads sql data

  Begin

  declare stucno char(3) ;

  declare cred int default 0;

  declare t_cred int default 0;

  declare done int default false;

  declare stucur cursor for select cno from score where sno=stuno and grade>=60;

  declare continue handler for not found set done=true;

  open stucur;

loop_cursor:loop

fetch stucur into stucno;

if done then leave loop_cursor; End if;

select credit into cred from course where cno=stucno;

set t_cred=t_cred+cred;

end loop;

return t_cred;

end$$

delimiter ;

 /**********End**********/


第3关:存储过程-调用函数count_credit

任务描述

本关任务:创建存储过程 p_count_credit,调用 count_credit 函数更新学生表的总学分值。

相关知识

为了完成本关任务,你需要掌握: 1.存储过程的定义; 2.存储过程的创建和查询; 3.存储过程的查询和删除。

存储过程的定义

存储过程Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的 SQL 语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用

简单的说存储过程就是具有名字的一段代码,用来完成一个特定的功能。

编程要求

根据提示,在右侧编辑器补充代码,创建存储过程 p_count_credit,调用count_credit 函数更新学生表的总学分值。

测试说明

平台会对你编写的代码进行测试,将调用你编写的存储过程p_count_credit,函数的count_credit的功能和第2关中的相同,具体输出请参考右侧测试集。

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
  DELIMITER $$

  CREATE PROCEDURE p_count_credit()

  BEGIN

  DECLARE stuno CHAR(6);

  DECLARE done int default false;

  DECLARE stucur CURSOR FOR SELECT sno FROM student;

  DECLARE CONTINUE HANDLER FOR not found set done=true;

  open stucur;

  loop_cursor:loop

  fetch stucur into stuno;

  if done then leave loop_cursor; end if;

  update student set totalcredit=count_credit(stuno) where sno=stuno;

  end loop;

  end$$

  delimiter ;
  
 /**********End**********/


第4关:创建触发器-计算总学分

任务描述

本关任务:创建触发器 sum_credit,实现对 student 表总学分的计算,当 score 中添加记录时,student 表总学分的值做相应改变。当课程成绩大于等于60分时,将该课程的学分加到该学生的总学分中。

相关知识

为了完成本关任务,你需要掌握: 1.触发器的定义; 2.触发器的创建; 3.after 触发器。

触发器的定义

触发器Trigger)是存储在系统内部的一段程序代码。

触发器和存储过程类似,可以把它看作是一个特殊的存储过程。两者的区别是,触发器无需人工调用,当程序满足定义条件时就会被 MySQL 自动调用。这些条件可以称为触发事件,包括 INSERT、UPDATE 和 DELETE 操作。

核心就是数据库 SQL 语言层面的代码封装与重用

触发器的创建

  • 下面我们来创建一个触发器
 
  1. CREATE TRIGGER trigger_name trigger_time trigger_event
  2. ON table_name FOR EACH ROW
  3. trigger_body
  4. trigger_time:触发器触发时机,有before和after
  5. trigger_event:触发器触发事件,有insert,update,delete三种
  6. trigger_body:触发器主体语句

after触发器

  • delete触发器

建一个触发器 t_d_s,当删除表 student 中某个学生的信息时,同时将 grade 表中与该学生有关的数据全部删除。

 
  1. CREATE TRIGGER trigger_t1
  2. AFTER DELETE ON student
  3. FOR EACH ROW
  4. BEGIN
  5. DELETE FROM grade WHERE studentid = old.studentid;
  6. END
  • UPDATE 创建一触发器 t_u_s,实现在更新学生表的学号时,同时更新 grade 表中的相关记录的 student 的 id 值。
 
  1. CREATE TRIGGER t_u_s
  2. AFTER UPDATE ON student
  3. for EACH ROW
  4. BEGIN
  5. UPDATE grade SET studentid = new.studentid WHERE studentid = old.studentid;
  6. END
  • INSERT 创建一个存储过程,根据 student 表中数据,一次性更新 class 表中每个班的人数
 
  1. CREATE PROCEDURE p_tao()
  2. BEGIN
  3. DECLARE num int;
  4. DECLARE cid VARCHAR(20);
  5. DECLARE done boolean DEFAULT true;
  6. DECLARE cur CURSOR FOR
  7. SELECT classid,COUNT(*)
  8. FROM student
  9. GROUP BY classid;
  10. DECLARE CONTINUE HANDLER FOR NOT found SET done = false;
  11. UPDATE class set studentnum = 0;
  12. OPEN cur;
  13. FETCH cur INTO cid,num;
  14. WHILE done DO
  15. UPDATE class SET StudentNum = num WHERE classid = cid;
  16. FETCH cur INTO cid,num;
  17. END WHILE;
  18. CLOSE cur;
  19. END
  20. CALL p_tao();

编程要求

根据提示,在右侧编辑器补充代码,创建触发器 sum_credit,实现对 student 表总学分的计算,当 score 中添加记录时,student 表总学分的值做相应改变。当课程成绩大于等于60分时,将该课程的学分加到该学生的总学分中。

测试说明

平台会对你编写的代码进行测试:平台会用“马小燕”为测试用例进行测试。

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
  delimiter $$
create trigger sum_credit after insert on score

  for each row

  Begin

  update student set totalcredit=totalcredit+

  (select credit from course where cno=new.cno)

  where sno=new.sno and new.grade>=60;

  end $$
  delimiter ;

  
 /**********End**********/


第5关:创建触发器-练习级联删除操作

任务描述

本关任务:创建级联删除触发器 del_student_score,当删除 student 表中的学生时,也删除 score 表中的对应学号的学生成绩记录。

相关知识

见第4关。

编程要求

根据提示,在右侧编辑器补充代码,创建级联删除触发器 del_student_score,当删除 student 表中的学生时,也删除 score 表中的对应学号的学生成绩记录。

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
 delimiter $$

  drop trigger if exists del_student_score$$

  create trigger del_student_score before delete

  on student

  for each row

  Begin

  delete from score where sno=old.sno;

  end$$

  delimiter ;

  
 /**********End**********/


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MYSQL实训七——存储过程、函数与触发器 的相关文章

  • Oracle 函数编译成功,但在执行 PLS-00221 时抛出错误:不是过程或未定义

    我有简单的oracle功能 create or replace function abs test func test in in number return number is test out number BEGIN test out
  • 使用存储过程并发访问MySQL数据库

    我有一个存储过程 它将读取然后增加数据库中的值 许多程序同时使用这个特定的过程 我担心并发问题 特别是读写器问题 有人可以建议我任何可能的解决方案吗 thanks 首先 正如另一篇文章中所述 使用 InnoDB 从 MySQL 5 5 开始
  • PHP 和 MySQLi 中没有选择数据库错误[重复]

    这个问题在这里已经有答案了 我必须从 MySQL 数据库中选择数据 我一直在寻找答案 但仍然没有找到 我正在学习W3School http www w3schools com php php mysql select asp 我的 MySQ
  • 查找缺失值

    我有一个表 有 2 个重要的列 DocEntry WebId 样本数据就像 DocEntry WebId 1 S001 2 S002 3 S003 4 S005 现在我们可以注意到 在 WebId 列中 S004 丢失了 我们如何通过查询找
  • 排除任何字段中具有 NULL 值的行结果?

    我有一个像这样的简单选择 SELECT FROM table WHERE fk id 10020 它可以工作 但有一些字段为 NULL 没有模式所以做了 SELECT FROM table WHERE fk id 10020 AND NOT
  • 如何使用Conda安装MySQLdb?

    我已经阅读了有关如何安装 MySQLdb 的几种不同的解释 但我不确定哪种情况适用于我 因为我的错误消息不同 我的系统似乎找不到 MySQLdb 我安装了 pymysql 但我需要导入 MySQLdb 才能使用该库中的过程 感谢您的帮助 c
  • PHP/MySQL:检索邻接列表模型中的单个路径

    有没有什么有效的方法可以在不限制深度的情况下根据节点的ID检索邻接列表模型中的单个路径 就像如果我有一个名为 Banana 的节点的 ID 我可以获得以下路径 Food gt Fruits gt Banana 如果不可能的话也不是什么大问题
  • 使用 JOIN 和 UNION 合并不同表中的记录

    我需要创建一个查询来组合两个表中的数据 我认为可能是 JOIN 和 UNION 的组合 在此示例中 我需要列出状态处于活动状态的所有姓名 仅一次 并将他们的葡萄酒 苏打水 晚餐 甜点和水果偏好组合起来 按姓名排序 我不确定单独的 JOIN
  • 使用聚合函数时减少 Athena 扫描的数据量

    以下查询扫描 100 MB 的数据 select from table where column1 val and partition id 20190309 然而 下面的查询扫描了 15 GB 的数据 有超过 90 个分区 select
  • 如何让MySQL数据库完全在内存中运行?

    我注意到我的数据库服务器支持内存数据库引擎 我想让一个已经运行 InnoDB 的数据库完全在内存中运行以提高性能 我怎么做 我探索了 PHPMyAdmin 但找不到 更改引擎 功能 假设您了解注释中提到的使用 MEMORY 引擎的后果 并且
  • SQL COUNT(*) 返回错误答案

    以下脚本应返回部门名称以及这些部门中的员工人数 营销 行政和销售部门有 0 名员工 但返回值不是 0 而是 1 我怎样才能纠正它 select Department Departments DepartmentID count as Num
  • 左连接,左表中没有重复行

    请看下面的查询 tbl 目录 Content Id Content Title Content Text 10002 New case Study New case Study 10003 New case Study New case S
  • 如何在 SQL 中编写 where 子句来按一天中的时间过滤 DATETIME 列?

    我有带有 DATETIME 列时间戳的数据 我想将其过滤到 DATETIME 介于上午 9 30 到下午 5 30 之间的任意一天的记录集 最好的方法是什么 更新 更改是因为我需要精确到分钟 而不仅仅是小时 对于那个很抱歉 您始终可以将其编
  • 在带有循环引用的表中插入 SQL

    我有 2 张桌子 Empleados numEmpl nombre apellido sexo telefono salario numDept Departamentos numDept nombreDept numDirect 在部门中
  • 获取SQL中前2个特殊字符之间的字符

    我有数据在sql 只是要注意 SQL STudio is the IDE like data a 10 b c a 1 b c 我想获取前两个符号之间的数据 Output 10 1 这就是我的方法 SELECT CAST
  • 对时间序列数据重新采样

    我有一个以毫秒为单位的时间序列列表 我想对时间序列进行重新采样并对组应用平均值 我如何在 Postgres 中实现它 重新采样 是指聚合一秒或一分钟内的所有时间戳 一秒或一分钟内的所有行形成一组 表结构 date x y z Use dat
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • 为什么运行 docker 容器后 mysql 数据所有权更改为 systemd-journal-remote

    我的mysql数据库存储在 home mysql代替 var lib mysql 该目录曾经属于mysql 但是 当我运行命令时docker compose up使用这个 yml 文件 version 3 services mariadb
  • 无法在 Centos 上安装 php-mysqli 扩展

    我正在尝试将 mysqli 扩展安装到 php yum install php mysqli 我收到下一个错误 Transaction Check Error file usr share mysql charsets Index xml
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N

随机推荐

  • Flutter: Dart 参数,以及 @required 与 required

    1 Dart 参数 Dart 函数的参数分 3 种类型 位置参数 命名参数 可选位置参数 1 1 位置参数 positional parameters 参数位置重要 名称任意 定义 void debugger String message
  • uniapp开发的App(安卓)端跳转uniapp微信小程序

    本文总结两种跳转方法 适合自己的才是最好的 1 根据微信开放文档提供的方法获取小程序的URL 两种 小程序的URL Scheme weixin dl business t TICKET 小程序的URL Link https wxaurl c
  • 宝塔控制面板无法访问,浏览器提示连接失败

    防火墙已经关闭 端口已经开好 但宝塔控制面板无法访问 浏览器提示连接失败 错误信息 火狐浏览器提示连接失败 解决思路 连接ssl重启宝塔 宝塔重启命令 bt restart
  • 全国地区树形结构列表。TreeNode工具

    Select select from shop region order by id ResultType java util LinkedList class 虽然这里用了LinkedList 但好像后面并没有用到 List
  • 三色标记算法

    什么是三色标记 CMS的运行过程中存在并发标记过程 由于不产生STW 所以对垃圾的清理必须存在标记和删除两个过程分开 而不能看到是垃圾就直接清除 否则会引起不必要的麻烦 CMS为了解决这个问题 采用了三色标记算法来记录对象是否已经被扫描过
  • 环境篇-在Qt工程中调用OpenSSL

    本文属于 OpenSSL加密算法库使用系列教程 之一 欢迎查看其它文章 我们知道OpenSSL有一个命令行工具openssl exe 可以通过命令实现很多的操作 同时OpenSSL还提供了动态库 所以如果我们想调用OpenSSL 有2种方法
  • 树的应用举例

    二叉树 先序遍历 这里指根在先 from collections import deque class BitTree def init self self root None def insert self node pos pass s
  • meilisearch使用记录

    分页 查找内容 默认一页十条 def search q from size 10 return client index indexName search q opt params limit size offset from 当前页 st
  • 剖析RedHat Linux中三个重要内核文件

    在网络中 不少服务器采用的是Linux系统 为了进一步提高服务器的性能 可能需要根据特定的硬件及需求重新编译Linux内核 编译Linux内核 需要根据规定的步骤进行 编译内核过程中涉及到几个重要的文件 比如对于RedHat Linux 在
  • (简单成功)原生js实现点击复制文本

    目录 背景 核心代码 案例 背景 我们开发中可能会有点击复制的功能 那么下面将讲述 核心代码 select 方法用于选择该元素中的文本 document execCommand copy 执行浏览器复制命令 案例
  • 微信网页调用jssdk扫一扫,63002报错的坑,ios的兼容问题

    一 因为项目需要用到微信网页扫一扫功能 并且去找了很多文章都没有统一的整理 所以就整理了一下 比较常见的坑 1 如何在网页调用扫一扫功能 1 先引入npm npm install weixin js sdk 如果你需要用微信的支付那些api
  • PWN学习-ADworld刷题

    前言 搁置了一段时间没更博 经历了考试还有一些其他事 决心好好去学pwn 学习的方法打算是按照看视频课加刷题加查找资料来学习 先把新手题都刷了一遍 都是很入门的题目 没啥好提的 收获也少 然后去刷进阶的题 但是目前还没有遇到堆的题目 视频课
  • C语言队列的理解

    队列是一种特殊的线性表 特殊之处在与允许在表的前端 front 进行删除操作 而在表ide后端进行插入操作 和栈一样 队列时一种操作受限制的线性表 进行 插入操作的端称为队尾 进行删除操作的端称为队头 队列的数据元素称为队列元素 在队列中插
  • Spring cloud系列-Nacos:Nacos的使用和报错处理

    目前你让我刚接触SpringCloud就来说Nacos做注册中心的优劣 或者深入的讲解Nacos 可能是有点为难我 Nacos是阿里开源的一个项目 一个负责发现 配置 管理微服务的一个平台 也就是说微服务这一块他还是不错的 下面是Nacos
  • uniapp - App 超详细消息推送功能实现,从 0-1 实现官方 unipush 推送全步骤稳定性毋庸置疑(附带详细的可运行示例源码和注释,保证 100% 完美接入)苹果安卓手机

    效果图 网上的教程太乱用不了 无法改造成自己想要的效果 在uniapp中开发的app 安卓苹果 使用 unipush 官方推送 从0 1实现完整过程及功能开发 你可以直接复制示例源码 跟着教程一步步配置 注释详细 准备 消息
  • JS手动实现一个new操作符

    要手动实现一个 new 操作符 首先要知道 new 操作符都做了什么事 即构造函数的内部原理 1 创建一个新对象 2 链接到原型 将构造函数的 prototype 赋值给新对象的 proto 3 绑定this 构造函数中的this指向新对象
  • C语言libcurl库的使用

    C语言libcurl库的安装与使用 curl库的作用是访问http和HTTPS网站 HTTPS加密的网站 在linux和树莓派都可以 把curl 7 71 1 tar bz文件复制到linux的工作目录 home lth mkdir htt
  • 怎么获取别人服务器信息,【奇技淫巧】通过解密f5的cookie信息获得服务器真实内网IP...

    原标题 奇技淫巧 通过解密f5的cookie信息获得服务器真实内网IP 渗透测试过程中 经常会遇到目标服务器使用F5 LTM做负载均衡 如果能获取到目标服务器的真实IP地址 会给后续渗透带来一定便利 本文既是最近渗透遇到的一点点经验分享 F
  • E: Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/t

    sudo apt get remove libappstream3 转载于 https www cnblogs com steinven p 11141368 html
  • MYSQL实训七——存储过程、函数与触发器

    第1关 创建存储过程 任务描述 本关任务 创建存储过程 pro findname 对学生姓名进行模糊查找 输入任一字输出姓名中含有该字的全部学生 相关知识 为了完成本关任务 你需要掌握 1 存储过程的定义 2 存储过程的创建和查询 3 存储