SQL-存储过程、流程控制、游标

存储过程

存储过程概述

1.产生背景

  • 开发过程总,经常会遇到重复使用某一功能的情况

2.解决办法

  • MySQL引人了存储过程(Stored Procedure)这一技术

3.存储过程

  • 存储过程就是一条或多条SQL语句的集合
  • 存储过程可将一系列复杂操作封装成一个代码块,以便重复使用,从而减少工作量提升开发效率。

4.编译

  • SQL语句需先编译然后执行。
  • 存储过程将为了完成特定功能的SQL语句集,经编译后存储在数据库中。

4.使用

  • 通过指定存储过程的名字通过传参的方式对其进行调用。
  • 存储过程可看做是编程的函数,它允许以传参调用的访问方式。

存储过程入门案例

1.准备数据

  • 创建数据库
  • 创建学生表
  • 插入数据
DROP TABLE IF EXISTS student;CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT 'male'
);
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1001', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1002', 'wang', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1003', 'tywd', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1004', 'hfgs', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1005', 'qwer', 18, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1006', 'zxsd', 19, 'female');

2.编写存储过程

-- 改存储过程中依据指定年纪查询出符合条件的学生
delimiter //
create procedure procedureDemo01(in sage int)
beginselect * from student where age>sage;
end //
delimiter ;

3.关键词解释

(1)DELIMITER //

  • 声明当前段分隔符

  • 让编译器把两个//之间的内容当做存储过程的代码

  • MySQL 默认以 **;**为分隔符

    • 若没有声明分隔符,则编译器会把存储过程当成SQL语句进行处理,从而造成编译过程会报错

(2)DELIMITER ;

  • 把分隔符还原为默认分隔符;

  • DELIMITER也可以指定其他符号作为结束符

  • 注意:DELIMITER与要设定的结束符之间一定要有一个空格,否则设定无效

(3)CREATE PROCEDURE 存储过程名称(参数)

  • 创建存储过程

(4)BEGIN END

  • 过程体

  • 存储过程的过程体以BEGIN开始以END结束

4.调用存储过程

  • call 存储过程名(参数);调用存储过程
call procedureDemo01(15);

5.删除存储过程

  • DROP PROCEDURE 存储过程名;删除存储过程
drop procedure procedureDemo01;

存储过程的参数

  • 存储过程定义中可传参,可不传参

1.传参分类

CREATE PROCEDURE 存储过程名([[IN |OUT |INOUT ] 参数名 数据类型...])

2.IN

  • 输入参数,表示该参数的值必须在调用存储过程时指定
-- findStudentByAge,该存储过程中有个IN参数,该参数为INT类型叫做sage 
delimiter //
create procedure findStudentByAge(in sage int)
beginselect * from student where age=sage;
end //
delimiter ;
-- 调用存储过程
call findStudentByAge(16);

3.用户变量

(1)语法

@var_name

(2)创建用户变量

SET 用户变量=初始值;

(3)查看用户变量值

SELECT 用户变量;

(4)注意

  • 定义用户变量后可方便开发过程的代码编写,只要连接未关闭我们均可直接使用该变量。
  • 当连接关闭时所有客户变量将自动释放。

4.OUT参数

  • 表示输出参数,可在存储过程内改变该值并将其返回
-- 存储过程countStudent,该存储过程中有个OUT参数,该参数为INT类型叫做total。
-- 存储体中将统计的结果利用`INTO`存入total中。
-- 调用存储过程中将用户变量@number作为参数传入,然后利用`SELECT @number`参看结果。
delimiter //
create procedure countStudent(out total int)
beginselect count(*) into total from student;
end //
delimiter ;
set @number=0;
call countStudent(@number);
select @number;

5.INOUT参数

  • 表示输入输出参数,可在调用存储过程时指定该参数并在存储体中改变该值并将其返回
-- 存储过程searchStudentGender,该存储过程中有个INOUT参数,该参数为VARCHAR(50)类型叫做message。
-- message既当做输入参数又当做输出参数,即输入参数为学生的姓名lili返回的是学生的性别male。
-- 调用存储过程时将初始值为lili的用户变量@info传入存储过程,调用存储过程结束后再次查询@info的值为male。 
delimiter //
create procedure queryStudentGender(inout message varchar(50))
beginselect gender into message from student where sname=message;
end //
delimiter ;
set @info='lili';
call queryStudentGender(@info);
select @info;

变量

1.使用场景

  • 编写存储过程中有时需要使用变量保存数据处理过程中的值。

2.作用范围

  • BEGIN…END

3.语法

DECLARE varName dataType [DEFAULT value];
  • DECLARE:定义变量
  • varName:局部变量的名称
  • dataType:局部变量的类型
  • DEFAULT value:变量默认值

(1)变量赋值或修改变量值

SET varName = value;

(2)示例一

delimiter //
create procedure varTest01(in number1 int)
begin-- 声明变量declare number2 int;-- 声明变量resultdeclare result int;-- 为变量number2赋值set number2 = 99;-- 为变量result赋值set result = number1 + number2;-- 显示resultselect result;
end //
delimiter ;
-- 调用存储过程
call varTest01(1);

(2)示例二

-- 若存在存储过程findStudent,将之删除
drop procedure if exists findStudent;
delimiter //
create procedure findStudent(in studentID char(6))
begindeclare studentName varchar(59);declare studentGender varchar(50);-- 将查询结果保存至变量studentName和studentGender中select sname,gender into studentName,studentGender from student where sid=studentID;-- 显示studentName和studentGender中保存的值select studentName,studentGender;
end //
delimiter ;
-- 调用存储过程
call findStudent('S_1001');

流程控制

1.流程控制概述

  • 流程控制语句用于将多个SQL语句划分或组合成符合业务逻辑的代码块。

2.流程控制语句

  • IF语句
  • CASE语句
  • LOOP语句
  • WHILE语句
  • LEAVE语句
  • ITERATE语句
  • REPEAT语句

3.IF

(1)IF概述

  • IF语句包含多个条件判断,根据结果为TRUE、FALSE执行语句。
  • IF语句于编程语言中学得if、else if、else类似

(2)语法

IF expr_condition THEN statement_list[ELSE expr_condtion THEN statement_list] ...[ELSE statement_list]
END IF

(3)示例代码

drop procedure if exists ifTest;
delimiter //
create procedure ifTest(in num int)
begindeclare result varchar(20);if num < 0 then set result = 'negative number';elseif num = 0 thenset result = 'number is zero';else set result = 'positive number';end if;select result;
end //
delimiter;
-- 调用存储过程
call ifTest(-1);

4.CASE 语句

(1)CASE概述

  • CASE 是另一个条件判断的雨具,改雨具有两种语法格式

(2)CASE语法格式一

CASE case_exprWHEN  value THEN statement_list[WHEN value THEN statement_list] ...[ELSE statement_list]
END CASE;

(3)CASE语法格式一示例

DROP PROCEDURE
IFEXISTS testCase01;
delimiter //
create procedure testCase01(in num int)
begindeclare result varchar(20);case numwhen num>0 set result = 'num is 正数';when num=0 set result = 'num is zero';else set result = 'num is 负数';end case;select result;
end //
delimiter ;
call testCase01(1);

(4)CASE语法格式二

CASEWHEN expr_condition THEN statement_list[WHEN expr_condition THEN statement_list] ...[ELSE statement_list]
END CASE;

(5)CASE语法格式二示例

delimiter //
create procedure testCase02(in num int)
begindeclare result varchar(20);casewhen num > 0 then set result = 'positive number';when num = 0 then set result = 'number is zero';else set result = 'positive number';end case;select result;
end //
delimiter ;
call testCase02(1);

5.LOOP语句

(1)LOOP语句概述

  • LOOP 是一种循环语句,用来重复执行某些语句。
  • 在执行过程中可使用LEAVE语句跳出循环,也可以嵌套IF等判断语句。

(2)LOOP语法

[loop_label:] LOOPstatement_list
END LOOP [loop_label]
  • loop_label:标识标注名称,该参数可省略

(3)LOOP语句示例

delimiter //
create procedure testLoop(in start1 int ,in end1 int)
begindeclare sumResult int default 0;add_loop: loopset sumResult = sumResult + start1;set start1 = start1 + 1;if start1 > end1 thenleave add_loop;end if;end loop add_loop;select sumResult;
end //
delimiter ;
call testLoop(0,100);

6.ITERATE

(1)ITERATE概述

  • 表示再次循环,该语句作用是将执行顺序转到语句段开头处再执行,它与编程语言的continue非常类似;

(2)ITERATE 语法

ITERATE label

(3)示例

DROP PROCEDURE IF EXISTS testITERATE;DELIMITER //CREATE PROCEDURE testITERATE(IN start1 INT,IN end1 INT)BEGINDECLARE sumResult INT DEFAULT 0;add_loop: LOOPSET sumResult=sumResult+start1;SET start1=start1+1;IF start1 <= end1 THENITERATE  add_loop;ELSE LEAVE add_loop;END IF;END LOOP add_loop;SELECT sumResult;END //
DELIMITER ;
call testITERATE(0,100);

7.REPEAT

(1)REPEAT概述

  • 表示带判断条件的循环过程
  • 每次语句执行完毕之后,会对条件表达式进行判断,若表达式为TRUE则循环结束,否则重复执行。
  • REPEAT类似于do…while。

(2)REPEAT语法

[repeat_label:] REPEATstatement_list
UNTIL expr_condtion
END REPEAT [repeat_label]

(3)REPEAT语法实例

 DELIMITER //CREATE PROCEDURE testREPEAT(IN start INT,IN end INT)BEGINDECLARE sumResult INT DEFAULT 0;REPEATSET sumResult = sumResult + start;SET start=start+1;UNTIL start > endEND REPEAT;SELECT sumResult;
END //
DELIMITER ;
call testREPEAT(0,100);

8.WHILE

(1)WHILE概述

  • 用于带判断条件的循环过程。
  • 与REPEAT不同,WHILE语句先判断表达式,为真则执行循环内的语句,否则退出循环。
  • WHILE与编程语言的while类似。

(2)WHILE语法格式

[while_label:] WHILE expr_condition DOstatement_list
END WHILE [while_label]

(3)WHILE语法示例


DROP PROCEDURE IF EXISTS testWHILE;)
DELIMITER //
CREATE PROCEDURE testWHILE(IN start INT,IN end INT)BEGINDECLARE sumResult INT DEFAULT 0;WHILE  start <= end DOSET sumResult = sumResult + start;SET start=start+1;END WHILE;SELECT sumResult;END //
DELIMITER ;
call testWHILE(0,100);

游标(cursor)

1.游标概述

  • 游标提供一种对 从表中检索出的数据进行操作的灵活手段。
  • 本质而言,游标实际上是一种能 从包括多条数据记录的结果集中每次提取一条记录的机制。
  • 例如,存储过程中查询语句可能会返回多条记录或大量记录,此时就需要游标来逐条读取查询结果集中的记录。

2.游标使用步骤

  • 定义游标
  • 打开游标
  • 使用游标
  • 关闭游标
  • 释放游标

(1)定义游标

declare 有标明 cursor for select_statement;

(2)打开游标

open 游标名;

(3)使用游标

declare 变量1 与对应列值相同的数据类型
declare 变量2 与对应列值相同的数据类型
declare 变量3 与对应列值相同的数据类型
fetch next from 游标 [into 变量名1,变量名2,变量名3,...]
  • declare:声明变量用于存储查询出来的数据;
  • fetch:获取数据并保存至 declare 声明的变量中;
  • fetch next:获取下一行数据
  • 注意:初始状态中,游标默认指向数据集的第一行数据之前。故,在使用游标时应该执行fetch next 操作让其指向第一行数据。

(4)关闭游标

close 游标名;

(5)释放游标

deallocate 游标名;

3.游标示例一

delimiter //
create procedure cursorTest01()
begin-- 声明与对应列类型相同的4个变量declare studentID char(6);declare studentName varchar(50);declare studentAge int;declare studentGender varchar(50);-- 定义游标studentCursordeclare studentCursor cursor for select * from student;-- 打开游标open studentCursor;-- 使用游标fetch next from studentCursor into studentID,studentName,studentAge,studentGender;-- 显示结果select studentID,studentName,studentAge,studentGender;-- 关闭游标close studentCursor;
end //
delimiter ;
-- 调用存储过程
call cursorTest01();
  • 在存储过程中,查询后得到的结果为表中所有数据。
  • 在此,利用 fetch next 将结果集中的第一条数据的sid,sname,age,gender对应地保存至 studentID,studentName,studentName,studentAge,studentGender变量中。

4.游标示例二

drop procedure if exists cursorTest02;
delimiter //
create procedure cursorTest02()
begin-- 声明与对应列类型相同的4个变量declare studentID char(6);declare studentName varchar(50);declare studentAge int;declare studentGender varchar(50);-- 声明计数器declare count int default 0;declare total int default 0;-- 定义游标studentCursordeclare studentCursor cursor for select * from student;set total = (select count(*) from student);-- 打开游标open studentCursor;-- 使用游标-- 利用 REPEAT 语句循环取出结果集中的数据REPEATfetch next from studentCursor into studentID,studentName,studentAge,studentGender;-- 显示结果select studentID,studentName,studentAge,studentGender;set count = count + 1;until count = totalend repeat;-- 关闭游标close studentCursor;
end //
delimiter ;
-- 调用存储过程
call cursorTest02();

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

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

相关文章

【【萌新的STM32的学习--非正点原子视频的中断设计思路】】

萌新的STM32学习–非正点原子视频的中断设计思路 我们分析而言 我们对于PA0 的设计就从此而来 对于边沿触发的选择我们已经有所了解了 我们下拉&#xff0c;但是当我们摁下开关的时候 从0到1 导通了 所以这个是下拉 上升沿触发 而对于KEY0 我们摁下是使得电路从原来悬空高阻态…

算法通关村第10关【黄金】| 归并排序

归并排序&#xff08;Merge Sort&#xff09;是一种常见的基于比较的排序算法&#xff0c;它的主要思想是分而治之&#xff08;Divide and Conquer&#xff09;。它的核心思想是将一个大的问题分解为小的子问题&#xff0c;解决子问题&#xff0c;然后将它们合并&#xff08;me…

开启EMQX的SSL模式及SSL证书生成流程

生成证书 首先&#xff1a;需要安装Openssl 以下是openssl命令 生成CA证书 1.openssl genrsa -out rootCA.key 2048 2.openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -subj "/CCN/STShandong/Ljinan/Oyunding/OUplatform/CNrootCA" -out ro…

算法通关村-----数组实现加法专题问题解析

数组实现整数加法 问题描述 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外&#xff0c;这个整数不会以零开头。详见leetcode66 问题…

模型的保存加载、模型微调、GPU使用及Pytorch常见报错

序列化与反序列化 序列化就是说内存中的某一个对象保存到硬盘当中&#xff0c;以二进制序列的形式存储下来&#xff0c;这就是一个序列化的过程。 而反序列化&#xff0c;就是将硬盘中存储的二进制的数&#xff0c;反序列化到内存当中&#xff0c;得到一个相应的对象&#xff…

Java 中的 IO 和 NIO

Java 中的 IO 和 NIO Java IO 介绍Java NIO&#xff08;New IO&#xff09;介绍windows 安装 ffmpeg完整示例参考文献 Java IO 介绍 Java IO&#xff08;Input/Output&#xff09;流是用于处理输入和输出数据的机制。它提供了一种标准化的方式来读取和写入数据&#xff0c;可以…

理解 std::thread::join

C多线程并发编程入门&#xff08;目录&#xff09; 本文用最简单易懂的实际案例&#xff0c;讲清楚了 join 的实际内涵&#xff0c;保证你过目不忘。 Hello join 示例 join 函数是我们接触C多线程 thread 遇到的第一个函数。 比如&#xff1a; int main() {thread t(f);t.…

C++面试知识点总结

知识点总结 <<符号表示该语句将把这个字符串发送给cout&#xff1b;该符号指出了信息流动的路径&#xff1b;cout的对象属性包括一个插入运算符&#xff08;<<&#xff09;&#xff0c;它可以将其右侧的信息插入到流中&#xff0c;endl:重起一行。在输出流中插入en…

哈希的应用——位图

文章目录 前言1. 面试题思考2. 位图2.1 位图的概念2.2 思路讲解及代码实现结构定义构造函数set和reset接口实现set和reset测试观察test接口实现test接口测试思考 3. 位图的应用习题1习题2习题3 4. 总结5. 源码5.1 bitset.h5.2 Test.c 前言 前面的文章里我们学习了哈希表&#x…

赞奇科技参与华为云828 B2B企业节,云工作站入选精选产品解决方案

8月27日&#xff0c;由华为云携手上万家伙伴共同发起的第二届 828 B2B 企业节拉开帷幕&#xff0c;围绕五大系列活动&#xff0c;为万千中小企业带来精细化商机对接。 聚焦行业数字化所需最优产品&#xff0c;举办超1000场供需对接会&#xff0c;遍及20多个省100多个城市&…

【数据结构】动态数组(vector)的基本操作,包括插入、删除、扩容、输出、释放内存等。以下是代码的解释和注释:

这段C代码实现了一个动态数组&#xff08;vector&#xff09;的基本操作&#xff0c;包括插入、删除、扩容、输出、释放内存等。以下是代码的解释和注释&#xff1a; // 引入标准输入输出库和标准库函数&#xff0c;用于后续的内存分配和打印输出等操作 #include <stdio.…

Python小知识 - 使用Python进行数据分析

使用Python进行数据分析 数据分析简介 数据分析&#xff0c;又称为信息分析&#xff0c;是指对数据进行综合处理、归纳提炼、概括总结的过程&#xff0c;是数据处理的第一步。 数据分析的目的是了解数据的内在规律&#xff0c;为数据挖掘&#xff0c;并应用于商业决策、科学研究…

Pytorch.tensor 相关用法

Torch.tensor.backward()方法的使用举例 理解optimizer.zero_grad(), loss.backward(), optimizer.step()的作用及原理 Autograd: 自动求导 import torchatorch.randn(2,2) # tensor默认requires_gradFalse a((a*3)/(a-1)) print(a.requires_grad) print(a.grad_fn) # leaf …

运行速度高达1.8GHz可编程采集网关

今天介绍下BL304这个设备。嵌入式ARM控制器BL304系列是一款专为工业控制领域设计的坚固型工控设备。它采用NXP公司的处理器I.MX8M Mini四核64位处理器&#xff0c;搭配四核 Cortex-A53单核Cortex-M4构架&#xff0c;运行速度高达1.8GHz&#xff0c;具有高度的稳定性和可靠性。 …

从0到1学会Git(第二部分):Git的本地操作和管理

写在前面:本文介绍了在本地仓库进行文件的处理以及本地的合并等操作。 前置知识:文件可以处在三个区域&#xff0c;分别为工作区&#xff0c;暂存区和本地仓库&#xff0c;我们此文的目标即是将文件存储在本地仓库中。我们可以将文件的区域理解为&#xff0c;cpu中&#xff0c…

计算机视觉主要任务

计算机视觉&#xff1a;使用计算机及相关设备对生物视觉的一种模拟。 主要包含6大任务&#xff0c;图像分类&#xff0c;目标检测&#xff0c;目标跟踪&#xff0c;语义分割&#xff0c;实例分割&#xff0c;影像重构。 图像分类&#xff1a;根据图像信息中所反映的不同特征&am…

数据结构与算法复杂度介绍

目录 一、基本概念 二、时间复杂度 【2.1】时间复杂度概念 【2.2】大O的渐进表示法 【2.3】举例时间复杂度计算 三、空间复杂度 一、基本概念 数据结构&#xff1a;相互之间存在一种或者多种特定关系的数据元素的集合。在逻辑上可以分为线性结构&#xff0c;散列结构、树…

Redis List类型命令 - Set类型命令 - SortedSet类型命令

目录 List类型 什么是双向链表呢&#xff1f; List类型的特征&#xff1a; List的常用命令 LPUSH和RPUSH的区别&#xff1a; LPOP和RPOP的区别&#xff1a; LPUSH和RPUSH的使用 LPOP和RPOP的使用 LRANGE key star end&#xff1a;返回一段距离范围内所有的元素 BLPOP…

最小生成树Kruskal、Prim算法C++

什么是最小生成树 连通图&#xff1a; 在无向图中&#xff0c;若从顶点v1到顶点v2有路径&#xff0c;则称顶点v1和顶点v2是连通的。如果图中任意一对顶点都是连通的&#xff0c;则称此图为连通图。 生成树&#xff1a; 一个连通图的最小连通子图称作为图的生成树。有n个顶点的…