文理学院数据库应用技术实验报告3

文理学院数据库应用技术实验报告3

实验名称 自定义函数和流程控制语句的使用 实验日期 2024年10月18日
课程名称 数据库技术应用 实验项目 自定义函数和流程控制语句的使用

一、实验目的

  1. 用户自定义变量的使用(难点)
  2. 数据库基本函数的学习及使用(重点)
  3. 使用select语句调用函数

二、实验原理

  1. 用户自定义变量:

(1) 用户会话变量

sql 复制代码
set @变量名1=表达式1 [,@变量名2=表达式2, ...];
select @变量名1:=表达式1 [,变量名2:=表达式2, ...];

(2) 局部变量

sql 复制代码
declare 变量名数据类型;
set 变量名=表达式;
  1. 语句块

(1) begin-end语句块

(2) 重置命令结束标记

sql 复制代码
delimiter $$
不可拆分的语句部分;
$$delimiter;
  1. 用户自定义函数
sql 复制代码
create function 函数名(参数1, 参数2, ...) returns 返回值的数据类型
[函数选项]
begin
​	函数体;
​	return语句;
end;
  1. 条件控制语句

(1) if语句

sql 复制代码
if 条件表达式1 then语句块1;
[elseif条件表达式2 then语句块2] ...
[else语句块n]
end if;

(2) case语句

sql 复制代码
case表达式
when值1  then语句块1;
when值2  then语句块2;
...
else语句块n;
end case;
  1. 循环语句

(1) while语句

sql 复制代码
[循环标签:]while条件表达式do
循环体;
end while [循环标签];

(2) leave语句

sql 复制代码
leave循环标签; 

(3) iterate语句

sql 复制代码
iterate循环标签;

(4) repeat语句

sql 复制代码
[循环标签:]repeat
循环体;
until条件表达式
end repeat [循环标签];

(5) loop语句

sql 复制代码
[循环标签:] loop
循环体;
if条件表达式then
leave [循环标签]; 
end if;
end loop;

三、实验设备、材料

安装了MySQLnavicat的主机

四、 实验步骤

请完成以下条件控制自定义函数练习

(1)使用条件控制语句的自定义函数:
  • 使用if语句完成本题:按托运规则,行李在50公斤及以下时,运费为2.5元/公斤;如超过50公斤,超过部分的运费为2.8元/公斤,不超过的部分依然以2.5元/公斤计数。定义函数fun_Calculate_Charges,根据行李重量作为函数参数,判断运费是多少作为返回值输出。

    sql 复制代码
    drop function if exists fun_Calculate;
    DELIMITER $$
    CREATE FUNCTION fun_Calculate(weight DECIMAL(5,2))
    RETURNS DECIMAL(7,2)
    DETERMINISTIC 
    BEGIN
      DECLARE charge DECIMAL(7,2);
      IF weight <= 50 THEN
        SET charge = weight * 2.5;
      ELSE
        SET charge = (50 * 2.5) + ((weight - 50) * 2.8);
      END IF;
      RETURN charge;
    END$$
    DELIMITER ;
    SELECT fun_Calculate(40) as a; 

使用case语句完成本题:通过判断成绩得到评判结果==(60分以下为不及格,60-69分为及格,70-79分为中等,80-89分为良好,90-100分为优秀)==。定义函数fun_Judge_Grade,根据0-100之间的成绩(小数)作为函数参数,判断级别作为返回值输出。

sql 复制代码
drop function if exists fun_Judge_Grade;
DELIMITER $$
CREATE FUNCTION fun_Judge_Grade(score DECIMAL(4, 2))
RETURNS VARCHAR(20)
DETERMINISTIC
BEGIN
  DECLARE grade VARCHAR(20);
  CASE
    WHEN score < 60 THEN
      SET grade = '不及格';
    WHEN score BETWEEN 60 AND 69 THEN
      SET grade = '及格';
    WHEN score BETWEEN 70 AND 79 THEN
      SET grade = '中等';
    WHEN score BETWEEN 80 AND 89 THEN
      SET grade = '良好';
    WHEN score BETWEEN 90 AND 100 THEN
      SET grade = '优秀';
    ELSE
      SET grade = '无效成绩';
  END CASE;
  RETURN grade;
END$$
DELIMITER ;
SELECT fun_Judge_Grade(85) as a; 
(2) 使用循环语句的自定义函数:
  • 使用while语句完成本题:找出 2020 年到 2050 年之间的闰年 (闰年算法:可被 4 整除,而不是被 100 整除,或被 400 整除)。请定义一个函数"fun_Leap",它可以根据两个年份作为函数参数,输出 所有符合条件的年份。

    sql 复制代码
    drop function if exists fun_Leap;
    DELIMITER $$
    CREATE PROCEDURE fun_Leap(IN startYear INT, IN endYear INT)
    BEGIN
      DECLARE year INT DEFAULT startYear;
      WHILE year <= endYear DO
        IF ((year % 4 = 0 AND year % 100 != 0) OR (year % 400 = 0)) THEN
          SELECT year AS 'Leap Year'; -- 输出符合条件的年份
        END IF;
        SET year = year + 1; -- 增加年份
      END WHILE;
    END$$
    DELIMITER ;
    CALL fun_Leap(2020, 2050) ;
  • 使用**while**语句完成本题:两个任意三位数之间有多少数?定义函数fun_Three_Digit_Number,根据两个整数作为函数参数,将所有两个整数之间的三位数全部输出。

    sql 复制代码
    DROP PROCEDURE IF EXISTS fun_Three_Digit_Number;
    DELIMITER $$
    CREATE PROCEDURE fun_Three_Digit_Number(start_num INT, end_num INT)
    BEGIN
        DECLARE current_num INT;
        SET current_num = start_num;
            WHILE current_num <= end_num DO
            IF current_num >= 100 AND current_num <= 999 THEN
                SELECT current_num AS three_digit_number;
            END IF;
            SET current_num = current_num + 1;
        END WHILE;
    END $$
    DELIMITER ;
    CALL fun_Three_Digit_Number(100, 200);
  • 选做题

写一个函数fun_Chinese_Currency,实现任意一个整数货币的数字作为函数参数,能够输出按位转换后的中文大写货币(六位以内),难点:诸位取数字问题,进位问题,连续0的问题。

例如:"1569",输出"壹仟伍佰陆拾玖元"

再如:"870064",输出"捌拾柒万零陆拾肆元"

​ "1500",输出"壹仟伍佰元"

sql 复制代码
DELIMITER $$  
  
CREATE FUNCTION fun_Chinese_Currency(num INT)  
RETURNS VARCHAR(50)  
BEGIN  
    DECLARE len INT;  
    DECLARE digit CHAR(1);  
    DECLARE position INT;  
    DECLARE result VARCHAR(50) DEFAULT '';  
    DECLARE units VARCHAR(20) DEFAULT '元拾佰仟万拾佰仟亿';  
    DECLARE chinese_digits VARCHAR(10) DEFAULT '零壹贰叁肆伍陆柒捌玖';  
    DECLARE zero_flag BOOLEAN DEFAULT FALSE;  
  
    -- 获取数字长度  
    SET len = LENGTH(num);  
      
    -- 遍历数字的每一位  
    SET position = 1;  
    WHILE position <= len DO  
        SET digit = SUBSTRING(num, len - position + 1, 1);  
          
        -- 处理零的情况  
        IF digit = '0' THEN  
            IF NOT zero_flag THEN  
                SET result = CONCAT(result, SUBSTRING(chinese_digits, 2, 1)); -- 添加零  
                SET zero_flag = TRUE;  
            END IF;  
        ELSE  
            SET result = CONCAT(result, SUBSTRING(chinese_digits, digit + 1, 1)); -- 添加对应中文大写数字  
            SET result = CONCAT(result, SUBSTRING(units, position, 1)); -- 添加单位  
            SET zero_flag = FALSE;  
        END IF;  
          
        -- 特殊处理:添加"万"和"亿"的单位,以及处理最高位的零  
        IF position = 4 AND len > 4 THEN  
            SET result = CONCAT(result, '万');  
            SET result = TRIM(TRAILING SUBSTRING(chinese_digits, 2, 1) FROM result); -- 去掉末尾的零  
            SET zero_flag = FALSE;  
            SET units = SUBSTRING(units, 5); -- 去掉已经用过的单位  
            SET position = position - 4; -- 重置位置,从新的四位开始  
            SET len = len - 4;  
            SET result = TRIM(LEADING SUBSTRING(units, 1, 1) FROM result); -- 去掉开头的单位(如果不需要)  
        END IF;  
          
        SET position = position + 1;  
    END WHILE;  
      
    -- 去除末尾多余的零和单位  
    SET result = TRIM(TRAILING SUBSTRING(units, 1, 1) FROM result);  
    SET result = TRIM(TRAILING SUBSTRING(chinese_digits, 2, 1) FROM result);  
      
    -- 如果全是零,特殊处理  
    IF result = '' THEN  
        SET result = SUBSTRING(chinese_digits, 2, 1) || '元';  
    END IF;  
      
    RETURN result;  
END$$  
  
DELIMITER ;

测试:

sql 复制代码
SELECT fun_Chinese_Currency(1569) AS result; -- 输出: 壹仟伍佰陆拾玖元  
SELECT fun_Chinese_Currency(870064) AS result; -- 输出: 捌拾柒万零陆拾肆元  
SELECT fun_Chinese_Currency(1500) AS result; -- 输出: 壹仟伍佰元
相关推荐
i道i9 分钟前
MySQL win安装 和 pymysql使用示例
数据库·mysql
小怪兽ysl10 分钟前
【PostgreSQL使用pg_filedump工具解析数据文件以恢复数据】
数据库·postgresql
武子康14 分钟前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
wqq_99225027740 分钟前
springboot基于微信小程序的食堂预约点餐系统
数据库·微信小程序·小程序
爱上口袋的天空42 分钟前
09 - Clickhouse的SQL操作
数据库·sql·clickhouse
Oak Zhang2 小时前
sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
redis·mysql·缓存
聂 可 以2 小时前
Windows环境安装MongoDB
数据库·mongodb
web前端神器2 小时前
mongodb多表查询,五个表查询
数据库·mongodb
门牙咬脆骨2 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存
门牙咬脆骨2 小时前
【Redis】GEO数据结构
数据库·redis·缓存