头歌实训之存储过程、函数与触发器

news2025/7/16 8:19:09

🌟 各位看官好,我是maomi_9526

🌍 种一棵树最好是十年前,其次是现在!

🚀 今天来学习C语言的相关知识。

👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更多人哦

目录

第1关:创建存储过程

第2关:创建函数-count_credit

第3关:存储过程中使用游标

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

第5关:创建触发器-级联删除

总结:头歌第二关及第三关

问题分析:


第1关:创建存储过程

任务描述
本关任务:创建存储过程,实现对学生姓名进行模糊查询。

相关知识
为了完成本关任务,你需要掌握:
1.存储过程的定义;
2.存储过程的创建;
3.存储过程的执行。

存储过程的定义
 存储过程(Stored Procedure)是数据库中一组预编译的SQL语句集合,存储在数据库中,可以被应用程序调用。存储过程可以包含复杂的逻辑、变量、条件判断和循环等,能够实现一些复杂的业务逻辑,提高代码的复用性和执行效率。

存储过程的创建
创建存储过程格式:

DELIMITER //
CREATE PROCEDURE 过程名([参数列表])
BEGIN
    -- SQL语句
END //
DELIMITER ;

  • DELIMITER:MySQL 默认的语句分隔符是分号(;),但在存储过程中,分号可能会被用作语句的分隔符,因此需要使用 DELIMITER 关键字来改变分隔符,通常将其改为 // 或其他符号,以免与存储过程内部的分号冲突。
  • 存储过程名称:存储过程的名称,用于后续调用存储过程时标识该存储过程。
  • 参数列表:存储过程的参数,可以有输入参数(IN)、输出参数(OUT)和输入输出参数(INOUT)。参数的格式为 参数名 参数类型,例如 IN id INT 表示一个输入参数 id,类型为整数。
  • BEGIN...END:存储过程的主体部分,包含需要执行的 SQL 语句。

执行存储过程

  • 调用存储过程的语法如下:

CALL 存储过程名称(参数值);

  • 存储过程名称:要调用的存储过程的名称。
  • 参数值:调用存储过程时传递的参数值(实参),参数值的顺序和类型应与存储过程定义时的参数列表一致。

编程要求

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

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


开始你的任务吧,祝你成功!

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

 /**********End**********/
DELIMITER ;

第2关:创建函数-count_credit

任务描述
本关任务:创建和使用存储函数。

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

  • 创建存储函数;
  • 调用存储函数。

创建存储函数

  • 存储函数(Stored Function)是一种在数据库中存储的可调用的函数,类似于存储过程,但存储函数的主要目的是返回一个值,而存储过程主要用于执行一系列操作。存储函数可以被 SQL 语句直接调用,也可以在其他存储过程或存储函数中调用。
  • 创建存储函数格式

DELIMITER //
CREATE FUNCTION 函数名称 (参数列表)
RETURNS 返回值类型  READS SQL DATA
BEGIN
    -- 函数的 SQL 语句
    RETURN 返回值;
END//
DELIMITER ;


调用函数

  • SELECT 函数名称(参数值);
  • 在表达式中使用函数名称(参数值)。

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

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


 开始你的任务吧,祝你成功!

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
  delimiter ##
  create Function count_credit(v_sno char(6))
  returns int reads sql data
  Begin
  declare sums int ;
  select sum(credit) into sums from course natural join score where grade >=60 and v_sno=sno;
    return sums;
  end ##
  delimiter ;
  
 /**********End**********/

第3关:存储过程中使用游标

任务描述
本关任务:创建存储过程 ,在存储过程中定义游标计算总学分。

相关知识
为了完成本关任务,你需要掌握:
1.游标的定义;
2.游标的使用。

游标的定义
游标(Cursor)主要用于存储过程和函数中,用于逐行处理查询结果集。

  • 在存储过程或函数中,使用 DECLARE CURSOR 语句来创建游标。

DECLARE cursor_name CURSOR FOR select_statement;

游标的使用

  • 打开游标

OPEN cursor_name;

  • 获取数据

FETCH cursor_name INTO var_name1, var_name2, ...;

  • 关闭游标

CLOSE cursor_name;


举例:通过游标获取users表中的id,name,并输出结果。

DELIMITER //
CREATE PROCEDURE process_users()
BEGIN
   -- 声明变量
   DECLARE finished INTEGER DEFAULT 0;
   DECLARE user_id INT DEFAULT 0;
   DECLARE user_name VARCHAR(50) DEFAULT '';
   -- 声明游标
   DECLARE my_cursor CURSOR FOR SELECT id, name FROM users;
   -- 声明结束处理
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
   -- 打开游标
   OPEN my_cursor;
   -- 获取数据
   fetch_loop: LOOP
       FETCH my_cursor INTO user_id, user_name;
       IF finished = 1 THEN
           LEAVE fetch_loop;
       END IF;
       -- 处理每一行数据
       SELECT user_id, user_name;
   END LOOP;
   -- 关闭游标
   CLOSE my_cursor;
END //
DELIMITER ;

编程要求
根据提示,在右侧编辑器补充代码,创建存储过程 p_count_credit,在存储过程中创建游标stucur保存所有学生的学号,使用loop循环从游标中提取每个学生的学号,根据当前学号调用count_credit 函数计算学生的总学分,并更新学生表中的总学分值。

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


开始你的任务吧,祝你成功!

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

 drop procedure if exists p_count_credit;
 delimiter ##
  create procedure  p_count_credit()
  begin
    declare v_sno varchar(20);
    declare v_credit int default 0;
    declare stucur cursor for select sno from student;
    declare exit handler for not found close stucur ;
    open stucur;
    while true do
    fetch stucur into v_sno;
    update student set totalcredit =count_credit(v_sno) where sno=v_sno;
    end while;
    close stucur;
    select *from student;
    end ##
  delimiter ;
 /**********End**********/

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

任务描述
本关任务:创建触发器 sum_credit,实现对 student 表总学分的计算。

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

触发器的定义
触发器(Trigger)是一种特殊的存储过程,它在表上的数据发生变化(如INSERT、UPDATE 和 DELETE操作)时自动执行。触发器的主要作用是维护数据的完整性和一致性,或者在数据变化时执行一些自动化的操作。

  • 触发时机:触发器可以设置在数据操作之前(BEFORE)或之后(AFTER)执行。
  • 触发事件:可以是INSERT、UPDATE或DELETE操作。

创建触发器的语法:


CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
FOR EACH ROW
BEGIN
    -- 触发器要执行的SQL语句
END;

  • BEFORE 或 AFTER 指定触发器应在事件之前还是之后触发。
  • INSERT, UPDATE, 或 DELETE 指定触发器应该响应的事件类型。

触发器表

  • 在 MySQL 触发器中,NEW 和 OLD 是两个特殊的虚拟表(实际上它们是行数据的引用),用于访问触发事件中涉及的数据。这两个虚拟表的具体含义和用途取决于触发器所关联的操作类型(INSERT、UPDATE 或 DELETE)。
  • NEW 表
    • NEW 表表示即将插入到表中的新行数据,或者在更新操作中表示更新后的新值。
    • 可用场景: 在 BEFORE INSERT 和 AFTER INSERT 中,NEW 表示将要插入的新行。 在 BEFORE UPDATE 和 AFTER UPDATE 中,NEW 表示更新后的字段值。
    • 用法:可以通过 NEW.column_name 来访问或修改某一列的值。

示例
(1)创建一触发器 t_u_s,实现在更新学生表的学号时,同时更新 grade 表中的相关记录的 student 的 id 值。

CREATE TRIGGER t_u_s
AFTER UPDATE ON student
for EACH ROW
BEGIN
    UPDATE grade SET studentid = new.studentid WHERE studentid = old.studentid;
END

  • OLD 表
  • OLD 表表示被删除或更新的旧行数据。
  • 可用场景: 在 BEFORE DELETE 和 AFTER DELETE 中,OLD 表示将要被删除的行。 在 BEFORE UPDATE 和 AFTER UPDATE 中,OLD 表示更新前的字段值。
  • 用法:可以通过 OLD.column_name 来访问某一列的值,但不能对其进行修改(因为它是只读的)。

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

CREATE TRIGGER trigger_t1
AFTER DELETE ON student
FOR EACH ROW
BEGIN 
    DELETE FROM grade WHERE studentid = old.studentid;
END

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

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


开始你的任务吧,祝你成功!

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
 delimiter ##
  create trigger sum_credit
  after insert on score for each row
  Begin
  if(new.grade>=60) then
        update student set totalcredit =totalcredit+(select credit from course where cno=new.cno)
        where student.sno=new.sno;
    end if;
    end ##
    delimiter ;

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

第5关:创建触发器-级联删除

任务描述
本关任务:创建级联删除触发器 。

相关知识
为了完成本关任务,你需要掌握:
1.级联删除的定义;
2.级联删除的工作原理。

级联删除的定义

  • 级联删除(Cascade Delete)是数据库管理系统中的一种功能,用于定义外键约束时指定的删除规则。当一个表中的记录被删除时,所有关联的记录也会根据级联删除规则自动删除。这确保了数据的一致性,避免出现孤立记录(即那些指向已删除记录的外键值)。

级联删除的工作原理

  • 级联删除的工作原理
    • 假设你有两个表:Parent 和 Child。Child 表通过外键关联到 Parent 表。当你在 Parent 表上设置级联删除时,如果从 Parent 表中删除一条记录,那么所有在 Child 表中与这条记录相关联的记录也将被自动删除。

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

测试说明
平台会对你编写的代码进行测试。


开始你的任务吧,祝你成功!

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
  delimiter ##
  create trigger del_studnet_score
  before delete on student for each row
  begin
    delete from score where sno=old.sno;
    end ##
  delimiter ;
 /**********End**********/

总结:头歌第二关及第三关

常见答题系统工作原理: 

问题分析:

在头歌平台的测试过程中,由于他们只进行公开测试用例的验证,部分潜在的逻辑错误可能没有被及时发现。这种情况尤其会影响到 MySQL 相关的习题,因为这些习题通常会涉及到数据库操作的细节,如果没有合适的隐藏测试用例,某些问题可能不会暴露。

例如实验五第二关:

自己代码:官方代码:
 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
  delimiter ##
  create Function count_credit(v_sno char(6))
  returns float reads sql data
  Begin
  declare sums float;
  select sum(credit) into sums from course natural join score where grade >=60 and v_sno=sno;
    return sums;
  end ##
  delimiter ;
  
 /**********End**********/
CREATE DEFINER=`root`@`localhost` FUNCTION `count_credit`(stuno CHAR(6)) 
RETURNS int(11)
    READS SQL DATA
BEGIN
    DECLARE stucno CHAR(3);  
    DECLARE cred INT DEFAULT 0;
    DECLARE t_cred INT DEFAULT 0;
    DECLARE done INT DEFAULT FALSE;
    
    -- 定义游标,从score表中获取学生所选课程编号
    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
 

 勘误:因为官方只进行公开实例进行测试,这里都可以进行通过

 

Mysql习题一般都是继续使用官方的代码进行测试,如果你在第三关依旧写出float的代码 */

 use teachingdb;
 /****请在此编写代码,操作完毕之后点击评测******/
 
 /**********Begin**********/
select sum(credit) from score natural join course  where sno='96002';
 drop procedure if exists p_count_credit;
 delimiter ##
  create procedure  p_count_credit()
  begin
    declare v_sno varchar(20);
    declare v_credit float default 0;
    declare stucur cursor for select sno from student;
    declare exit handler for not found close stucur ;
    open stucur;
    while true do
    fetch stucur into v_sno;
    select sum(credit) into v_credit from score natural join course where grade>=60 and sno=v_sno;
    update student set totalcredit =ifnull(v_credit,0) where sno=v_sno;
    end while;
    close stucur;
    select *from student;
    end ##
  delimiter ;
 /**********End**********/

由于头歌平台的测试机制仅依赖于公开的测试用例,这导致了部分潜在的逻辑问题没有被及时发现。尽管我们无法修改平台的测试方式或其隐藏的测试用例,但我们可以选择按照平台提供的标准函数进行测试,以确保代码在实际评测时能够正确运行。

本次纠错并没有涉及复杂的新知识点,而是希望同学们能够理解,为什么在这种情况下,某些潜在的错误未被立即发现,当大家出现这种情况也可以通过下面这种方法来通过测试:

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

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

相关文章

【华为】防火墙双击热备-之-主备模式-单外网线路-分享

FW1和FW2的业务接口都工作在三层,上行连接二层交换机。上行交换机连接运营商的接入点,运营商为企业分配的IP地址为100.100.100.2。现在希望FW1和FW2以主备备份方式工作。正常情况下,流量通过FW1转发;当FW1出现故障时,流…

川翔云电脑32G大显存集群机器上线!

川翔云电脑今日重磅推出32G 大显存机型,为游戏玩家、设计师、AI 开发者等提供极致云端算力体验! 一、两大核心配置,突破性能天花板 ✅ 32G 超大显存机型 行业领先:搭载 NVIDIA 专业显卡,单卡可分配 32G 独立显存&am…

加里·基尔代尔:CP/M之父与个人计算时代的先驱

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 加里基尔代尔:CP/M之父与个人计算时代的先驱 一、早年生活与教育背景 1.…

静态多态和动态多态的区别

C多态机制深度解析 多态是面向对象编程的核心特性,允许通过统一接口执行不同实现。在C中,多态表现为基类指针或引用调用虚函数时,根据实际对象类型执行对应派生类的函数逻辑。 基础实现示例 定义基类与派生类,演示动态绑定…

Burp靶场JWT学习笔记1

JWT(JSON Web Token) 从其名字就可以看出来,它具有表示身份的作用,其本质是将用户信息储存到一串json字符串中再将其编码得到一串token JWT由三部分组成,分别是 Header,Payload,Signatrue JWTBase64(Header).Base6…

C++?类和对象(下)!!!

一、前言 在之前我们已经讨论过了有关类和对象的前置知识以及类中的六大默认成员函数,在本期我们继续再讨论类和对象中剩余的友元、初始化列表等相关知识,如果需要再了解之前的知识的话,链接奉上:C?类和对象&#xff0…

FastAPI 零基础入门指南:10 分钟搭建高性能 API

一、为什么选择 FastAPI? 想象一下,用 Python 写 API 可以像搭积木一样简单,同时还能拥有媲美 Go 语言的性能,这个框架凭借三大核心优势迅速风靡全球: 开发效率提升 3 倍:类型注解 自动文档,…

机器人新革命:Pi 0.5如何让智能走进千家万户

在科技飞速发展的今天,机器人技术正在以一种令人惊喜的方式贴近我们的生活。最近,Physical Intelligence 公司推出了 Pi 0.5 版本,这一创新设计不仅颠覆了传统机器人的运作模式,更让我们看到了未来智能设备融入日常生活的无限可能…

从数据结构说起(一)

1 揭开数据结构神奇的面纱 1.1 初识数据结构 在C的标准库模板(Standard Template Library,STL)课程上,我初次结识了《数据结构》。C语言提供的标准库模板是面向对象程序设计与泛型程序设计思想相结合的典范。所谓的泛型编程就是编写不依赖于具…

Git基本使用(很详细)

一:Git 概述 1.1 定义:分布式版本控制系统 1.2 版本控制 (1)定义: 版本控制时一种记录文件内容变化,以便将来查阅特定版本修订情况的系统 (2)举例 多副本 优化: 不使用多…

仓颉编程语言最佳实例 “Hello, world!”

仓颉编程语言最佳实例 “Hello, world!” The Best Practice to Cangjie Programming Language - “Hello, world!” BY JACKSON 1. 仓颉集成开发工具(IDE)安装 打开Chrome浏览器,访问仓颉编程语言官网:https://cangjie-lang.…

[mysql]窗口函数

目录 窗口函数: 为何要学习窗口函数,与mysql5.7实现语句对比 现在我们介绍一下窗口函数: 函数规则 1序号函数 2分布函数 3前后函数 5其他函数 总结 窗口函数: 首先数据库的迁移是非常慢的,大家学习新特性的时候要考虑自己公司的数据库版本是不是和自己学习的吻合 为何…

内存四区(栈)

今天我再次学到了有趣的知识,内存四区! 内存四区分为代码区,全局区,栈区,堆区,今天我们详细来讲讲栈区! 内存四区和栈区都是用来存放数据的,而栈区存放的数据具体有两类 1.形参数…

新零售行业时代:如何用科技驱动传统零售的转型升级​​

新零售行业时代:如何用科技驱动传统零售的转型升级​​ ​​“在变化的世界中,唯一不变的是变化本身。”​​ ​​一、传统零售的困局:当“生存”成为一场鏖战​​ 街角的便利店老板老王,每天凌晨4点起床进货,却在月…

长途骑行装备攻略:VELO维乐 Angel Revo坐垫伴我畅享旅途

工作忙碌了很久,终于迎来了一个难得的假期。我决定和朋友一起踏上一场长途骑行之旅,远离城市的喧嚣,去寻找那份久违的宁静与自由。这次旅行,不仅是为了旅途风景的放松,更是为了体验一场身体与心灵的挑战。而朋友推荐的…

WebcamJS中文文档

文章目录 WebcamJS针对Chrome 47及以上版本的重要说明浏览器支持演示示例开源协议快速入门指南配置初始化拍摄照片自定义图像大小裁剪图像翻转图像(镜像模式)冻结/预览图像设置备用SWF文件位置重置(关闭)API 参考自定义事件向服务器提交图像跟踪上传进度包含在现有表单中自…

微软官网Win10镜像下载快速获取ISO文件

如何从微软官网轻松下载win10镜像?win10镜像的下载方式主要包括两种: 目录 一:借助官方工具 二:直接微软官网通过浏览器进行下载。 三:实现方法与步骤: 1:利用微软官方提供的MediaCreationT…

逆向|dy|a_bogus|1.0.1.19-fix.01

2025-04-26 请求地址:aHR0cHM6Ly93d3cuZG91eWluLmNvbS91c2VyL01TNHdMakFCQUFBQV96azV6NkoyMG1YeGt0eHBnNkkzRVRKejlyMEs3d2Y2dU9EWlhvd2ttblZWRnB0dlBPMmMwN2J0WFotcVU4V3M 个人主页的视频数据 我们需要逆向这个接口,所以现在需要分析这个请求, 分析这几个数据包可以发现: 只有…

高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!

目录 思路"情境 对象 问题"型 课题选题的类型有哪些呢?这要从课题题目的构成说起。通过对历年来国家社会科学基金立项项目进行分析,小编发现,课题选题类型非常丰富,但一般是围绕限定词、研究对象和研究问题进行不同的组…

springboot项目配置nacos,指定使用环境

遇到这样一个问题,在开发、测试、生成环境之间切换的问题。 大多数的操作是通过修改spring.profiles.active来确定指向使用的环境配置文件,对应项目中需要增加对应的配置文件。 但是现在几乎所有公司都会有代码管理不管是SVN、git,这样就会涉…