MySQL-存储过程

介绍

基本语法

创建

调用

查看

删除

变量

系统变量

查看

设置

用户定义变量

赋值

使用

局部变量

声明

赋值

流程控制

参数

条件结构

IF

case

循环结构

while

repeat

loop

游标

条件处理程序


介绍

举个简单的例子,我们先select某数据,然后update,再update。这一系列操作指令是在MySQL中

下达的,然后指令传输到应用层,那么导致的问题就是,多次的指令传输会涉及到网络的请求。

所以存储过程就是,由一系列SQL语句经过编译后的指令集合,通过调用这个集合可以简化开发者的流程。最重要的是,能够减少数据在数据库和应用服务器之间的传输,提高数据处理的效率。

储存过程的思想很简单,就是在SQL语言层面的代码的封装和重用。

存储过程的特点:

  1. 封装、复用
  2. 可以接受参数、也可以返回数据
  3. 减少网络层的交互,提升效率

基本语法

创建

复制代码
create procedure p1() --存储过程名称,也可以添加参数
begin
    --具体的SQL语句
end;

调用

复制代码
call p1();

查看

  • 通过MySQL系统中的信息查看

    select *from information_schema.ROUTINES where ROUTINE_SCHEMA = 'text';
    --数据库名

  • 查看创建语句

    show create procedure p1;

删除

复制代码
drop procedure [if exist] p1;

**注意!!!**如果使用命令行执行存储过程的创建语句,会报错:

这是因为,在命令行中以分号为一句命令的结束,所以会导致报错。

所以在命令行中执行创建语句时,应该使用delimiter关键字指定命令结束符:

复制代码
delimiter $$  --指定两个美元符号为结束符号

create procedure p1() --存储过程名称,也可以添加参数
begin
    -----;
end;$$

变量

系统变量

系统变量是MySQL服务器指定的,不是用户定义的,属于服务器层面,Global(全局变量)、Session(会话变量,只代表当前会话)

查看

复制代码
show variables;
--show global variables;
--show session variables;

show variables like 'ac%';
--模糊匹配

select @@activate_all_roles_on_login;
--查找指定的系统变量名

设置

复制代码
set session 系统变量名 = 值;
--set global 系统变量名 = 值;

注意:

  • 当没有指定global和session时,系统默认是session会话变量

  • 当mysql重启时没所有设置的全局参数将会失效,要想不失效,可以在配置文件中配置

用户定义变量

赋值

复制代码
set @myname = 'John';
set @myage := 10; 
--相当于定义了两个变量,并且赋值

set @mynumber = 12345 , @myaddress = '北京市';
--可以同时定义两个用户变量

select set @mycolor := '中国红';
--可以使用select进行赋值

select count(*) into @mynum from users;
--可以使用其他表的字段来进行赋值

使用

复制代码
select @mycolor,@myage;

局部变量

声明

复制代码
declare user_num int;
--user_num是局部变量名

赋值

与用户自定义变量赋值相似

流程控制

参数

复制代码
create procedure p2(in score int,out ret varchar(10))
begin
    if score >=15 then
        set ret = '优秀';
    else
        set ret = '及格';
    end if;
end;

call p2(18,@ret);
select @ret;

运行结果:

条件结构

IF

复制代码
create procedure p2()
begin
    declare score int default 20;
    declare ret varchar(10);
    if score >=15 then
        set ret = '优秀';
    else
        set ret = '及格';
    end if;
    select ret;
end;

call p2();

还是比较好理解的,类似于编程语言中的IF语句。

case

复制代码
create procedure p3(in month int)
begin
    declare ret varchar(10);
    case
        when month>=1 and month<=3 then
            set ret := '第一季度';
        when month>=4 and month<=6 then
            set ret := '第二季度';
        when month>=7 and month<=9 then
            set ret := '第三季度';
        when month>=10 and month<=12 then
            set ret := '第四季度';
        else set ret := '非法参数';
    end case;

    select concat('您输入的月份为:',month,' 所属季度为:',ret);
end;

call p3(12);

循环结构

while

WHILE 条件 DO

SQL逻辑语句

END WHILE;

演示

输入一个参数n,返回从1到n的累加

复制代码
create procedure p4(in n int)
begin
    declare total int default 0;
    while n>=1 do
        set total = total + n;
        set n = n - 1;
    end while;
    select total;
end;

call p4(10);

运行结果

repeat

满足条件退出循环

repeat

SQL逻辑语句

UNTIL 条件

end repeat;

loop

loop一般配合下面两个语句使用:

  1. LEAVE(直接退出循环)

  2. ITERATE(跳过本次循环的剩下语句,然后进入下一次循环)

    create procedure p4(in n int)
    begin
    declare total int default 0;

    复制代码
     sum loop:
         if n<=0 then
             leave;
         end if;
    
         set total = total + n;
         set n = n - 1;
     end loop sum;
    
     select total;

    end;

    call p4(10);

游标

游标是用来存储查询数据集的数据类型,在存储过程或函数过程中对结果集进行循环的处理。

  • 声明游标

declare 游标名 cursor 查询结果集;

复制代码
--输入年龄上限,将所有小于该年龄的数据的部分字段,作为一个游标

create procedure p5(in n int)
begin
    declare uname varchar(10);
    declare ugender varchar(10);
    declare u_cursor cursor for select user_name,user_gender from users where user_age<=n;

    drop table if exists u_name_gen;
    create table if not exists u_name_gen(
        id int primary key auto_increment,
        name varchar(10),
        gender varchar(10)
    );

    open u_cursor;
    while true do
        fetch u_cursor into uname,ugender;
        insert into u_name_gen values (null,uname,ugender);
    end while;
    close u_cursor;

end;

call p5(32);

这里要注意的是,表确实创建成功了,但是MySQL依然会报错:

这里的原因在于存储过程中的循环没有有效的停止。

条件处理程序

条件处理程序用于在存储过程中抛出异常时,解决问题的相应步骤。

相关推荐
橙序研工坊1 小时前
MySQL的基础语法1(增删改查、DDL、DML、DQL和DCL)
数据库·sql·mysql·database
晴天Y281 小时前
redis部署架构
数据库·redis·架构
gjc5922 小时前
MySQL源码学习系列(二)--面试高频问题:general log、slowlog记录顺序
数据库·学习·mysql·面试·职场和发展
晓oi2 小时前
MySQL———作业实验
数据库·mysql
hh_fine2 小时前
解决 “Cannot read SQL script from class path resource [sql/XX.sql]“ 错误
数据库·sql
余华余华2 小时前
VSCODE npm: 因为在此系统上禁止运行脚本。有关详细信息,请参阅 ...
java·服务器·数据库·笔记·oracle
不剪发的Tony老师2 小时前
IvorySQL:兼容Oracle数据库的开源PostgreSQL
数据库·postgresql·oracle
独行soc2 小时前
2025年渗透测试面试题总结-某快手-安全工程师(题目+回答)
网络·数据库·python·安全·面试·职场和发展·红蓝攻防
赴前尘2 小时前
chromem-go + ollama + bge-m3 进行文档向量嵌入和查询
开发语言·数据库·golang
Austindatabases3 小时前
数据库界的“申公豹”,带云DBA走出--救生筏困境!
数据库·dba