• MySQL数据库————存储过程和函数


    系列文章目录


    在这里插入图片描述


    前言

    SQL语言作为高级语言,除了简单的查询语句与定义语句,还支持函数的定义(自定义函数用的较少,大多时候用库函数),当然,除了函数,MySQL还支持存储过程,由于MySQl的独特性,他的用法和其他的语言也有一些差距;


    一、函数

    一丶数据库的库函数

    1.聚合函数

    聚合函数是对一组值进行计算和返回单个值。
    ①.统计函数:count
    select count() from class; -- 统计班级个数;
    条件统计:
    select count(*) from class where c_stunum>60; -- 统计学生人数大于60的班级个数;
    ②.求最大值:max
    select max(c_stunum) from class; select * from class where c_stunum=max(c_stunum); -- 统计学生人数最多的班级人数;
    ③.求和函数:sum
    select sum(c_strnum) from class; -- 求所有班级中学生人数的和;
    除了这些函数,还有像avg,min函数,他们的用法都很相似,就不做过多的介绍;

    2.日期时间函数

    ①.获取当前时间:now
    基本格式:now();
    如:insert into <表名> values now();
    在这里插入图片描述
    ②.获取日期时间类型中的数据:date()
    select date('2000-1-1 6:30:30'); -- 截取日期:

    在这里插入图片描述
    ③.获取指定日期时间数据类型数据中的时间数据time
    select time("2020-7-31 14:36:31"); -- 截取时间;
    在这里插入图片描述
    ④.将日期转换为字符串类型date_format()
    select date_format(now(),"% Y-%m-%d %H:%i:%s"); -- 后面的字符串类型可以自己定义;
    在这里插入图片描述

    3.常用库函数

    ①.小写字母转大写:upper
    select upper('abc');
    ②.求字符串子串:substring
    select substring("123abc@#$XYZ",3,8);
    ③.四舍五入函数:round()
    1.select round(123.456); -- 只保留整数
    2.select round(123.456,1);-- 保留1位小数
    ④.求次方函数:power,pow
    select power(4,5);
    举一反三:
    select power(9,1/2);-- 求9的开根号;
    ⑤.获取当前数据库名:database()
    select database();
    ⑥.获取字符串的长度:length()
    select length("123,456,7,dfghr");
    ⑦.字符串连接函数,连接多个字符串:concat()
    select concat("1,34",'123','4frghy');

    上面的所有函数源代码:
    -- ①.小写字母转大写:`upper`
    select upper('abc');
    -- ②.求字符串子串:`substring`
    select substring('123abc@#$XYZ',3,8);  -- 从第三个开始,截取8个长度的子串;
    -- ③.四舍五入函数:`round()`
    select round(123.456); -- 只保留整数
    select round(123.456,1);-- 保留1位小数
    -- ④.求次方函数:`power,pow`
    select power(4,5);
    -- 举一反三:
    select power(9,1/2); -- 求9的开根号;
    -- ⑤.获取当前数据库名:`database()`
    select database();
    -- ⑥.获取字符串的长度:`length()`
    select length("123,456,7,dfghr");
    -- ⑦.字符串连接函数,连接多个字符串:`concat()`
    select concat("1,34",'123','4frghy');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    二、自定义函数

    数据库中的自定义函数和c语言类似,可以自定义函数,编辑函数所执行的代码,使其完成自己想要的功能。

    1.自定义函数的创建

    ①.创建自定义函数的基本格式:

    #自定义函数;
    create function power2()
    returns 返回值类型
    begin
      函数体语句
      return (函数返回结果)
    end;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    例如:创建一个函数,求两数和;

    -- 创建一个求和函数
    create function sum1(x int,y int)
    returns int
    return x+y;  -- 单条语句可以不使用begin,end;
    set global log_bin_trust_function_creators=true;  -- 关闭生命周期安全检查;
    select sum1(2,3); -- 结果查询;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    函数注意事项

    一.如果函数体较为复杂,或者执行语句较多,需要使用delimiter,和begin,end;由于要使用关键字:delimiter,后面介绍过后再详细讲解函数体语句较多的写法;
    二.函数里面无法使用select,create等动态SQL语句;如果要使用这些,就要用到存储过程;

    2.自定义结束符

    MySQL数据库中默认语句的结束符为“;”,此外MySQL数据库还支持自定义结束符,自定义结束符的关键字:delimiter
    自定义结束符的基本格式:
    delimiter <符号>;
    我们在定义函数的时候就会用到自定义结束符;

    #自定义结束符delimiter在函数中的使用;
    delimiter //  -- 定义分隔符为//,此后的结束符都是//;
    create function sum1(x int,y int)
    returns int
    begin
    return x+y
    end //
    delimiter ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.自定义函数的调用

    函数调用的基本格式为:select 函数名(函数参数);
    如:select sum1(3,2);

    4.自定义函数的删除

    删除自定义函数的恶基本格式:drop function 函数名;
    如:drop function sum1;

    三.存储过程

    存储过程和函数类似,可以理解成为数据库里一种特殊的函数对象,其也可以用于自定义功能,并且功能更加强大,所以MySQL数据库中一般使用存储过程比使用自定义函数方便。
    存储过程关键字:procedure

    1.创建无参存储过程

    创建无参存储过程的基本格式:

    # 存储过程的创建和使用
     delimiter <自定义结束符>
    create procedure 存储过程名()
    begin
    SQL语句1;
    SQL语句2;
    ······
    end <自定义结束符>
    delimiter;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    例如:

    delimiter //
    create procedure select_stu()
    begin -- 复合语句开始,相当于c++语言中的大括号;
    select s_id from student where s_id>3;  -- 存储过程支持SQL语句;
    select s_name from student where s_id>3;
    select s_cid from student where s_id>3;
    end//
    delimiter ;
    call select_stu();  -- 执行存储过程与视图相似;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.存储过程的调用

    存储过程的调用基本格式:call 存储过程(参数列表);

    3.查看已创建的指定存储过程的相关信息

    基本格式:show create procedure 存储过程名;

    4.查看已创建的所有存储过程的相关信息

    基本格式:show procedure ststus;
    在这里插入图片描述

    5.存储过程的删除

    基本格式:drop procedure <存储过程名>;

    6.修改存储过程

    MySQL还不支持修改存储过程的代码,只能先将原来的存储过程删除后,在重新创建;

    7.带参存储过程

    ①.创建带参存储过程的基本格式;

    delimiter 自定义结束符
    create procedure 存储过程名(参数类型 参数名1 数据类型,参数类型 参数名2 数据类型,参数类型 参数名3 数据类型·······)
    begin
    SQL语句;
    end 自定义结束符
    delimiter ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ②.参数类型
    MySQL数据库中存储过程的参数有3种类型,分别为:in,out,inout.
    1.-- in;传入型参数,用于将参数值传递进入存储过程中; 2.-- out传出型数据,用于将存储过程中的值传递出来; 3.-- inout传入传出型数据,既可以用于参数值传递进存储过程,又可以将值从存储过程传出;
    ③.带参存储过程的调用;
    call 存储过程(参数1,参数2,参数3·····)
    ④.带参存储过程的演示示例

    代码:

    #带参存储过程的演示示例
    -- 运用存储过程完成查询语句;
    delimiter //
    create procedure get_class_name(in cid int)
    begin
    select db_2.class.c_id from class where c_id=cid;
    end//
    delimiter ;
    -- 带参存储过程的调用;
    call get_class_name(100);
    call get_class_name(103);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    示例2:代码演示:

    #运用带参存储过程进行数据的插入;
    delimiter //
    create procedure insert_student(in sid int, sname varchar(20),scid int,ssex varchar(4),sage int) -- in可以省略,out,inout不可以省略;
    begin
    insert into student values(sid,sname,scid,ssex,sage);
    end//
    delimiter ;
    -- 带参调用
    call insert_student(116,"可可",2,'女',18);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    #运用带参存储过程进行修改操作;
    delimiter //
    create procedure update_student(in sid int,sname varchar(20))
    begin
    update student set s_name=sname where s_id=sid;
    end//
    delimiter ;
    -- 带参存储过程的调用;
    call update_student(100,'李娟');
    select * from student;-- 操作完成,查看;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    源代码呈现

    use db_2; -- 使用数据库;
    select now();  -- 获取现在的时间函数
    select date('2000-1-1 6:30:30'); -- 获取指定时间日期数据类型中的日期函数; 
    select time("2020-7-31 14:36:31"); -- 获取指定日期时间数据类型中的时间函数;
    select date_format(now(),"%Y-%m-%d    %H:%i:%s"); -- 将日期转换为字符串类型;
    -- ①.小写字母转大写:`upper`
    select upper('abc');
    -- ②.求字符串子串:`substring`
    select substring('123abc@#$XYZ',3,8);  -- 从第三个开始,截取8个长度的子串;
    -- ③.四舍五入函数:`round()`
    select round(123.456); -- 只保留整数
    select round(123.456,1);-- 保留1位小数
    -- ④.求次方函数:`power,pow`
    select power(4,5);
    -- 举一反三:
    select power(9,1/2); -- 求9的开根号;
    -- ⑤.获取当前数据库名:`database()`
    select database();
    -- ⑥.获取字符串的长度:`length()`
    select length("123,456,7,dfghr");
    -- ⑦.字符串连接函数,连接多个字符串:`concat()`
    select concat("1,34",'123','4frghy');
    
    #自定义函数;
    /*
    create function power2(
    returns 返回值类型
    begin
      函数体语句
      return (函数返回结果)
    end;
    );
    */
    -- 创建一个求和函数
    create function sum1(x int,y int)
    returns int
    return x+y;  -- 单条语句可以不使用begin,end;
    set global log_bin_trust_function_creators=true;  -- 关闭生命周期安全检查;
    select sum1(2,3); -- 结果查询;
    
    #自定义结束符delimiter在函数中的使用;
    delimiter //  -- 定义分隔符为//,此后的结束符都是//;
    create function sum1(x int,y int)
    returns int
    begin
    return x+y
    end //
    delimiter ;
    
    # 存储过程的创建和使用
    
    ```sql
    /* delimiter <自定义结束符>
    create procedure 存储过程名()
    begin
    SQL语句1;
    SQL语句2;
    ······`·
    end <自定义结束符>
    delimiter;
    */ 
    delimiter //
    create procedure select_stu()
    begin -- 复合语句开始,相当于c++语言中的大括号;
    select s_id from student where s_id>3;  -- 存储过程支持SQL语句;
    select s_name from student where s_id>3;
    select s_cid from student where s_id>3;
    end//
    delimiter ;
    call select_stu();  -- 执行存储过程与视图相似;
    
    #查看指定存储过程
    show create procedure select_stu;
    
    #查看存储过程;
    show procedure status;
    
    #带参存储过程的演示示例
    delimiter //
    create procedure get_class_name(in cid int)
    begin
    select db_2.class.c_id from class where c_id=cid;
    end//
    delimiter ;
    -- 带参存储过程的调用;
    call get_class_name(100);
    call get_class_name(103);
    
    
    #运用带参存储过程进行数据的插入;
    delimiter //
    create procedure insert_student(in sid int, sname varchar(20),scid int,ssex varchar(4),sage int) -- in可以省略,out,inout不可以省略;
    begin
    insert into student values(sid,sname,scid,ssex,sage);
    end//
    delimiter ;
    -- 带参调用
    call insert_student(116,"可可",2,'女',18);
    
    #运用带参存储过程进行修改操作;
    delimiter //
    create procedure update_student(in sid int,sname varchar(20))
    begin
    update student set s_name=sname where s_id=sid;
    end//
    delimiter ;
    -- 带参存储过程的调用;
    call update_student(100,'李娟');
    select * from student;-- 操作完成,查看;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110

    上面是我们本节讲解的代码示例,可以直接去运行,方便大家查看,我直接将代码发出来了;涉及到一些表的建立,只有使用了我给的表,上面的代码才能使用,代码在附件;

    附件(数据表代码)

    create database if not exists db_2;
    use db_2;
    #创建学生,班级,教师的数据表;
    -- 教师表
    create table teacher(
    t_id int primary key auto_increment,
    t_name varchar(20) not null,
    t_sex varchar(4) check(t_sex='男'||t_sex='女'),
    t_age int check(t_age>=20 and t_age<=60)
    )auto_increment=100;
    desc teacher;
    show columns from teacher;
    insert into teacher(t_name,t_sex,t_age) values('小威','男','28'),('靓靓','女','20'),('丸子','女','23'),
    ('易木','男','27'),('龙卷风','男','30'),('桃子','女','21'),('robert','男','40'),('可达','男','28'),
    ('荔枝','女','22'),('教主','男','29');
    -- 班级表
    create table class(
    c_id int primary key auto_increment,
    c_name varchar(30) not null,
    c_tid int, -- 班级的认可老师/班主任老师;
    c_stunum int default 0,-- 班级人数
    constraint for_CT foreign key(c_tid)
    references teacher(t_id)on update cascade on delete set null
    )auto_increment=100;
    insert into class(c_name,c_tid)values ('c语言',101),("c++",103),("数据结构",106),("win32",NULL),("游戏开发",107),
    ("QT",NULL),("Linux服务器",NULL);
    -- 学生表
    create table student(
    s_id int primary key auto_increment,
    s_name varchar(20) not null, -- 非空约束;
    s_cid int, -- 学生属于的班级
    s_sex varchar(4) check(s_sex='男' or s_sex='女'),
    s_age int check(s_age>=18 and s_age<=40),
    constraint for_SC foreign key(s_cid)  # 设置为外键; 
    references class(c_id) on update cascade on delete set null
    )auto_increment=100;
    insert into student(s_name,s_cid,s_sex,s_age) values ('陈小皮',100,'男',20),('吉利服',103,'男',20),
    ('张益达',100,'男',20),('萌萌',103,'女',20),('晓东',101,'男',20),('小蔡',null,'男',21),
    ('小玉',102,'女',21),('阿雪',103,'女',21),('如花',null,'女',25),('似玉',null,'女',24),('小桂子',null,'男',22),
    ('小强子',101,'男',23),('小吴',102,'男',24),('小花',100,'女',23),('小丸子',null,'女',20),('小红',101,'女',21);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    总结

    本节我们学习了函数和存储过程,函数我们只需要掌握常用的库函数就可以,自定义函数使用较少,不需要掌握,存储过程使用较多,由于它不被SQL语句限制,故掌握好存储过程更有利后面的使用。

  • 相关阅读:
    图像文件格式大全及代码检测方式
    算法学习:Leetcode-623. 在二叉树中增加一行
    Java线程同步:synchronized、Lock锁
    tailwindcss在使用cdn引入静态html的时候,vscode默认不会提示问题
    java-net-php-python-s2sh教学管理平台hsg8229AGA2修改回复计算机毕业设计程序
    消除两个inline-block元素之间的间隔
    矩阵分析与应用+张贤达
    小程序项目如何创建
    GPU--学习笔记
    (done) Positive Semidefinite Matrices 什么是半正定矩阵?如何证明一个矩阵是半正定矩阵? 可以使用特征值
  • 原文地址:https://blog.csdn.net/qq_59931372/article/details/126082821