当前位置:网站首页>MySQL查漏补缺(四)存储过程和游标

MySQL查漏补缺(四)存储过程和游标

2022-08-09 09:07:00 胡乐天

1. 存储过程

1.1 什么是存储过程?

简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。

1.2 为什么要使用存储过程

使用存储过程有三个好处:简单、安全、高性能。

注意:一般来说,存储过程比基本的SQL语句更加复杂,许多数据库管理员限制存储过程的创建权限,允许用户使用存储过程,但不允许他们创建存储过程。

1.3 使用存储过程

1.3.1 执行存储过程

CALL productpricing(@pricelow,@pricehigh,@priceaverage);

执行名为productpricing的存储过程,如果没有参数,则小括号中不写东西。

1.3.2 创建存储过程

创建一个简单的存储过程(在navicat中的函数中可以看见)

CREATE PROCEDURE diagToolCount () BEGIN
	SELECT
		school_code,
		school_term_id,
		count(*) 
	FROM
		ed_diag_tools 
	GROUP BY
	school_code,
	school_term_id;
	END;
语法:
create procedure 诊断过程名()
begin
Sql语句;
end;

注意:
1.Sql语句后的分号一定要加上。
2.如果有参数,则在小括号中列举出来,如果没有,则小括号中不写东西。
3.begin与end之间先定存储过程体。
4.如果使用mysql命令行来创建存储过程,默认Sql语句结束时,后跟分号。这样与存储过程结尾的分号相冲突,会导致存储过程不完整,导致报错。解决办法:delimiter //

以上语句为将//定义为分隔符,在end后使用//来表示结束。Sql语句照常书写,这样就不会冲突了。使用完成后,记得恢复分隔符,恢复语句:delimiter ;
5.执行上述存储过程:call diagToolCount();

1.3.3 删除存储过程

drop procedure diagToolCount;

注意:删除时只需要给出存储过程名即可,不需要加小括号。

1.3.4 使用参数

上述的存储过程只是一个简单的存储过程,它简单的显示Select语句的结果,一般,存储过程并不显示结果,而是把结果返回给你指定的变量。所谓的变量:就是内存中的一个特定的位置,用来临时存储数据。

关键字

out:从存储过程中传出的一个值。

in:传递到存储过程的值。

inout:对存储过程传入和传出。

out从存储过程中传递出的值——sql:

-- 1.删除存储过程,不删除,无法创建同名的存储过程
drop procedure diagToolCount;


-- 2.创建存储过程,out代表,从存储过程中传出一个值,count为传出值的名称,integer为传出值的类型
CREATE PROCEDURE diagToolCount (out count integer) BEGIN
	SELECT
		count(*) 
		into count -- 将count(*)给count
	FROM
		ed_diag_tools ;
	END;
	
	
	-- 3.执行存储过程,变量前面需要加@
	call diagToolCount(@count);
	
	-- 4.查询@count的数据为多少
	select @count

参数中同时含有in和out时——sql

-- 删除存储过程,不删除,无法创建同名的存储过程
drop procedure diagToolCount;


-- 传入参数为schoolCode,传出参数为result,即该学校下存储多少条数据
CREATE PROCEDURE diagToolCount (in schoolCode varchar(20),out result integer) BEGIN
	SELECT
		count(*)  
	FROM
		ed_diag_tools 
	where school_code=schoolCode into result;-- into
	END;
	
	
	-- 执行存储过程,变量前面需要加@
	call diagToolCount('ceshiSchool',@result);
	
	-- 查询@count的数据为多少
	select @result

1.3.5 检查存储过程

此语句会显示用来创建存储过程的create语句。

show create procedure diagToolCount;

2.游标

2.1 概念

MySQL检索操作返回一组称为结果集的行。这资源返回的行都是与SQL语句相匹配的行。有时,需要在检索出来的行中前进或者后退一行或者多行。这就是使用游标的原因。

游标(cursor)是一个存储在MySQL服务器上的数据库的查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。

**注意:**MySQL的游标只能用于存储过程。

2.2 使用游标

2.2.1 使用游标步骤

1.在使用游标前,必须声明(定义)它,这个过程实际上没有检索数据,它只是定义要使用的select语句。

2.一旦声明后,必须打开游标以供使用。这个过程用签名定义的select语句把数据实际检测出来。

3.对于填有数据的游标,根据需要取出(检索)各行。

4.在结束游标使用时,必须关闭游标。

2.2.2 创建游标

游标用declare语句创建。declare命名游标,并定义相应的select语句,根据需要带where和其他子句。(declare—>英译汉—>声明)

声明游标SQL:

create procedure diagTool()
begin
	declare tools cursor
	for
	select question from ed_diag_tools;
end;


这个存储过程并没有做很多事情,declare语句用来定义和命名游标,这里为tools。存储过程完成后,游标就消失了(因为它仅限于存储过程中)。

操作游标数据:

create procedure diagTool()
begin


-- 定义本地变量
	declare showSeq int;

-- 创建游标
	declare tools cursor
	for
	select show_seq from ed_diag_tools;
	
	-- 打开游标,在处理open语句时,执行查询,存储检索出的数据。
	open tools;
	
	-- 使用游标数据(fetch用来检查当前行的显示循序,并将该顺序放入到名为showSeq的局部变量中)
	fetch tools into showSeq;
	
	
	-- 关闭游标,Close释放游标所有的内部内存和资源,因此在每个游标不在需要时都应该关闭。
	-- 在一个游标关闭之后,如果没有重新打开,则不能使用它;
	-- 但是,使用声明过的游标不需要再次声明,使用open语句打开它就可以了。
	close tools;
	
	
end;

遍历操作游标数据:

create procedure diagTool()
begin


declare done boolean default 0;
declare o int;

declare tools cursor
for
select show_seq from ed_diag_tools;

-- 这句话的意思是,当fetch游标到了数据库表格最后一行的时候,设置done=1
declare continue handler for sqlstate '02000' set done=1;

open tools;

repeat
	fetch tools into o;
until done end repeat;
	
close tools;
	
end;


与上一端代码不同的是,这段代码的fetchrepeat内,因此它反复执行到done为真。

repeat循环语法:

		repeat
			代码逻辑
		until 循环结束时条件 end repeat;

注意:

declare语句存在特定的次序。使用declare定义的局部变量必须在定义任何游标或句柄之前定义;而句柄必须在游标之后定义,不遵守此顺序将产生错误消息。

真正使用(MySql必知必会中例子):

create procedure processorders()
begin

	declare done boolean default 0;
	declare o int;
	declare t int;
	
	declare ordernumbers cursor
	for
	select order_num from orders;
	
	declare continue handler for sqlstate '02000' set done = 1;
	-- 如果表ordertotals不存在,则创建该表
	create table if not exists ordertotals(order_num int,total decimal(8,2));
	
	open ordernumbers;
	
	repeat
		
		fetch ordernumbers into o;
		-- 执行名为ordertotal的存储过程,返回结果存储到t中
		call ordertotal(o,1,t);
		
		insert into ordertotals(order_num,total) values(o,t);
		
	until done end repeat;
	
	close ordernumbers;
end;

此存储过程不返回数据,但它能够创建和填充另一个表。

通过以上sql语句,我们就得到了存储过程、游标、逐行处理以及存储过程调用其他存储过程中的一个完成的工作样例。

原网站

版权声明
本文为[胡乐天]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_44613100/article/details/116595754