MySQL-存储过程和函数

举报
小奇JAVA 发表于 2022/09/25 06:33:05 2022/09/25
【摘要】 有志者,事竟成 文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。 ...

有志者,事竟成
文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

在这里插入图片描述


前言

存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句。存储过程和函数可以避免开发人员重复的编写相同的SQL语句。而且,存储过程和函数是在MySQL服务器中存储和执行的,可以减少客户端和服务器端的数据传输。

一、创建存储过程和函数

创建存储过程和函数是指将经常使用的一组SQL语句的组合在一起,并将这些SQL语句当作一个整体存储在MySQL服务器中。例如,银行经常需要计算用户的利息。不同类别的用户的利率是不一样的。这就可以将计算利率的SQL代码写成一个存储过程或者存储函数。只要调用这个存储过程或者存储函数,就可以将不同类别用户的利息计算出来。

1、创建存储过程

MySQL中,创建存储过程的基本形式如下:

create procedure sp_name([proc_parameter[,...]])
	[characteristic...] routine_body

  
 
  • 1
  • 2

其中,sp_name参数是存储过程的名称;proc_parameter表示存储过程的参数列表;characteristic参数指定存储过程的特性;routine_body参数是SQL代码的内容,可以用BEGIN…END来标志SQL代码的开始和结束。

proc_parameter中的每个参数由3部分组成。这3部分分别是输入输出类型、参数名称和参数类型。其形式如下:

[in | out | inout] param_name type 

  
 
  • 1

其中,IN表示输入参数;out表示输出参数;inout表示既可以是输入,也可以是输出;param_name参数是存储过程的参数名称;type参数指定存储过程的参数类型,该类型可以是MySQL数据库的任意数据类型。

2、创建存储函数

在MySQL中,创建存储函数的基本形式如下:

create function sp_name([func_parameter[,...]])
	returns type
	[characteristic ...] routine_body

  
 
  • 1
  • 2
  • 3

其中,sp_name参数是存储函数的名称;func_parameter表示存储函数的参数列表;returns type指定返回值的类型;characteristic参数指定存储函数的特性,该参数的取值与存储过程中的取值是一样的。

func_parameter可以由多个参数组成,其中每个参数由参数名称和参数类型组成,其形式如下:

param_name type

  
 
  • 1

其中,param_name参数是存储函数的参数名称;type参数指定存储函数的参数类型,该类型可以是MySQL数据库的任意数据类型。

下面创建一个名为name_from_employee的存储函数。代码如下:

在这里插入图片描述

3、变量的使用

在存储过程和函数中,可以定义和使用变量。用户可以使用declare关键字来定义变量。然后可以为变量赋值。这些变量的作用范围是begin…end程序段中。

1、定义变量

MySQL中可以使用declare关键字来定义变量。定义变量的基本语法如下:

declare var_name[,...] type [default value]

  
 
  • 1

其中,declare关键字是用来声明变量的;var_name参数是变量的名称,这里可以同时定义多个变量;type参数用来指定变量的类型;default value子句将变量默认值设置为value,没有使用default子句时,默认值为null。

下面定义变量my_sql,数据类型为int型,默认值为10。代码如下

declare my_sql int default 10;

  
 
  • 1

2、为变量赋值

MySQL中可以使用set关键字来为变量赋值。set语句的基本语法如下:

set var_name = expr[,var_name = expr]...

  
 
  • 1

其中,set关键字是用来为变量赋值的;var_name参数是变量的名称;expr参数是赋值表达式。一个set语句可以同时为多个变量赋值,各个变量的赋值语句之间用逗号隔开。

下面为变量my_sql赋值为30。代码如下:

set my_sql = 30;

  
 
  • 1

MySQL中还可以使用select…into语句为变量赋值。其基本语法如下:

select col_name[,...] into var_name[,...]
	from table_name where condition

  
 
  • 1
  • 2

其中,col_name参数表示查询的字段名称;var_name参数是变量的名称;table_name参数指表的名称;condition参数指查询条件。

下面从employee表中查询id为2的记录,将该记录的d_id值赋给变量my_sql。代码如下:

select d_id into my_sql
	from employee where  id = 2;

  
 
  • 1
  • 2

4、定义条件和处理程序

定义条件和处理程序是事先定义程序执行过程中可能遇到的问题。并且可以在处理程序中定义解决这些问题的办法。这种方式可以提前预测可能出现的问题,并提出解决方法。这样可以增强程序处理问题的能力,避免程序异常停止。MySQL中都是通过declare关键字来定义条件和处理程序。

1、定义条件

MySQL中可以使用declare关键字来定义条件。其基本语法形式如下;

declare condition_name condition for condition_value
condition_value;
	sqlstate[value] sqlstate_value | mysql_error_code

  
 
  • 1
  • 2
  • 3

其中,condition_name参数表示条件的名称;condition_value参数表示条件的类型;sqlstate_value参数和mysql_error_code参数都可以表示MySQL的错误。

下面定义“ERROR 1146(42S02)”这个错误,名称为can_not_find。可以用两种不同的方法来定义,代码如下:

//方法一:使用sqlstate_value
declare can_not_find condition for sqlstate '42S02';
//方法二:使用mysql_error_code
declare can_not_find condition for 1146;

  
 
  • 1
  • 2
  • 3
  • 4

2、定义处理程序

MySQL中可以使用declare关键字来定义处理程序。其基本语法如下:

declare handler_type handler for condition_value[,...] sp_statement
handler_type:
	continue | exit |undo
condition_value:
	sqlstate[value] sqlstate_value | condition_name | sqlwarning | not found | sqlexception | mysql_error_code

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

其中,handler_type参数指明错误的处理方式,该参数有3个取值。这3个取值分别是continue、exit和undo.continue表示遇到错误不进行处理,继续向下执行;exit表示遇到错误后马上退出;undo表示遇到错误后撤回之前的操作,MySQL暂时还不支持这种处理方式。

5、光标的使用

查询语句可能查询出多条记录,在存储过程和函数中使用光标来逐条读取查询结果集中的记录。有些书上将光标称为游标。光标的使用包括声明光标、打开光标、使用光标和关闭光标。光标必须声明在处理程序之前,并且声明在变量和条件之后。

1、声明光标

MySQL中使用declare关键字来声明光标。其语法的基本形式如下:

declare cursor_name cursor for select_statement;

  
 
  • 1

其中,cursor_name参数表示光标的名称;select_statement参数表示select语句的内容。

下面声明一个名为cur_employee的光标。代码如下:

declare cur_employee cursor for select name,age from employee;

  
 
  • 1

上面的示例中,光标的名称为cur_employee;select语句部分是从employee表中查询出name和age字段的值。

2、打开光标

MySQL中使用open关键字来打开光标。其语法的基本形式如下:

open cursor_name

  
 
  • 1

其中,cursor_name参数表示光标的名称。

下面打开一个名为cur_employee的光标,代码如下:

open cur_employee;

  
 
  • 1

3、使用光标

MySQL中使用fetch关键字来使用光标。其语法的基本形式如下:

fetch cur_employee into var_name[,var_name...];

  
 
  • 1

其中,cursor_name参数表示光标的名称;var_name参数表示将光标中的select语句查询出来的信息存入该参数中。var_name必须在声明光标之前就定义好。

下面使用一个名为cur_employee的光标。将查询出来的数据存入emp_name和emp_age这两个变量中,代码如下:

fetch cur_employee into emp_name, emp_age;

  
 
  • 1

上面的示例中,将光标cur_employee中select语句查询出来的信息存入emp_name和emp_age这两个变量中。emp_name和emp_age必须在前面已经定义。

4、关闭光标

MySQL中使用close关键字来关闭光标。其语法的基本形式如下:

close cursor_name;

  
 
  • 1

其中,cursor_name参数表示光标的名称。

下面关闭一个名为cur_employee的光标。代码如下:

close cur_employee;

  
 
  • 1

6、流程控制的使用

存储过程和函数中可以使用流程控制来控制语句的执行。MySQL中可以使用IF语句、CASE语句、LOOP语句、LEAVE语句、ITERATE语句、REPEAT语句和WHILE语句来进行流程控制。

1、if语句
if语句用来进行条件判断。根据是否满足条件,将执行不同的语句。其语法的基本形式如下:

if search_condition then statement_list
[elseif search_condition then statement_list]...
[else statement_list]
end if

  
 
  • 1
  • 2
  • 3
  • 4

其中,search_condition参数表示条件判断语句;statement_list参数表示不同条件的执行语句。

下面是一个if语句的示例。代码如下:

if age>20 then set @count1=@count1+1;
	elseif age=20 then @count2=@count2+1;
	else @count3=@count3+1;
end if;

  
 
  • 1
  • 2
  • 3
  • 4

该示例根据age与20的大小关系来执行不同的set语句。如果age值大于20,那么将count1的值加1;如果age值等于20,那么将count2的值加1;其他情况将count3的值加1,。if语句都需要使用end if来结束。

2、case语句
case语句也用来进行条件判断,其可以实现比if语句更复杂的条件判断。case语句的基本形式如下:

case case_value
	when when_value then statement_list
	[when when_value then statement_list]...
	[else statement_list]
end case

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

其中,case_value参数表示条件判断的变量;when_value参数表示变量的取值;statement_list参数表示不同when_value值的执行语句。

case语句还有另一种形式。该形式的语法如下:

case 
	when search_condition then statement_list
	[when search_condition then statement_list]...
	[else statement_list]
end case;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

其中,search_condition参数表示条件判断语句;statement_list参数表示不同条件的执行语句。

下面是一个case语句的示例。代码如下:

case age
	when 20 then set @count1=@count1+1;
	else set @count2=@count2+1;
end case;

  
 
  • 1
  • 2
  • 3
  • 4

代码也可以是下面的形式:

case 
	when age=20 then set @count1+1;
	else set @count2=@count2+1;
end case;

  
 
  • 1
  • 2
  • 3
  • 4

本示例中,如果age值为20,count1的值加1;否则count2的值加1。case语句都要使用end case结束。

3、loop语句
loop语句可以使某些特定的语句重复执行,实现一个简单的循环。但是loop语句本身没有停止循环的语句,必须是遇到leave语句等才能停止循环。loop语句的语法的基本形式如下:

[begin_label:] loop
	statement_list
end loop [end_label]

  
 
  • 1
  • 2
  • 3

其中,begin_label参数和end_label参数分别表示循环开始和结束的标志,这两个标志必须相同,而且都可以省略;statement_list参数表示需要循环执行的语句。

下面是一个loop语句的示例。代码如下:

add_num: loop
	set @count=@count+1;
end loop add_num;

  
 
  • 1
  • 2
  • 3

该示例循环执行count加1的操作。因为没有跳出循环的语句,这个循环成了一个死循环。loop循环都以end loop结束。

4、leave语句

leave语句主要用于跳出循环控制。其语法形式如下:

leave label

  
 
  • 1

其中,label参数表示循环的标志。

下面是一个leave语句的示例。代码如下:

add_num: loop
	set @count=@count+1;
	if @count=100THEN
		leave add_num;
end loop add_num;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

该示例循环执行count加1的操作。当count的值等于100时,则leave语句跳出循环。

5、ITERATE语句

ITERATE语句也是用来跳出循环的语句。但是,ITERATE语句是跳出本次循环,然后直接进入下一次循环。ITERATE语句的基本语法形式如下:

add_num: loop
	set @count=@count+1;
	if @count=100 THEN
	 	leave add_nul;
	else if mod(@count,3)=0 then
		iterate add_num;
	select * from employee;
end loop add_num;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该示例循环执行count加1的操作,count值为100时结束循环。如果count的值能够整除3,则跳出本次循环,不再执行下面的select语句。

6、repeat语句

repeat语句是有条件控制的循环语句。当满足特定条件时,就会跳出循环语句。repeate语句的基本语法形式如下:

[begin_label:] repeat
	statement_list
	until search_condition
end repeat [end_label]

  
 
  • 1
  • 2
  • 3
  • 4

其中,statement_list参数表示循环的执行语句;search_condition参数表示结束循环的条件,满足该条件时循环结束。

下面是一个iterate语句的示例。代码如下:

repeat
	set @count=@count+1;
	until @count=100
end repeate;

  
 
  • 1
  • 2
  • 3
  • 4

该示例循环执行count加1的操作,count值为100时结束循环。repeat循环都用end repeat结束。

7、while语句

while语句也是有条件控制的循环语句。但while语句和repeat语句是不一样的。while语句是当满足条件时,执行循环内的语句。while语句的基本语法形式如下:

[begin_label:] while search_condition DO
	statement_list
end while [end_label]

  
 
  • 1
  • 2
  • 3

其中,search_condition参数表示循环执行的条件,满足该条件时循环执行;statement_list参数表示循环的执行语句。

下面是一个iterate语句的示例。代码如下:

while @count<100 DO
	set @count=@count+1;
end while;

  
 
  • 1
  • 2
  • 3

该示例循环执行count加1的操作,count值小于100时执行循环。如果count值等于100了,则跳出循环。While循环需要使用end while来结束。

二、调用存储过程和函数

存储过程和存储函数都是存储在服务器端的SQL语句的集合。要使用这些已经定义好的存储过程和存储函数就必须要通过调用的方式来实现。存储过程是通过CALL语句来调用的。而存储函数的使用方法与MySQL内部函数的使用方法是一样的。执行存储过程和存储函数需要拥有execute权限。execute权限的信息存储在information_schema数据库下面的user_privileges表中。

1、调用存储过程

MySQL中使用CALL语句来调用存储过程。调用存储过程后,数据库系统将执行存储过程的语句。然后,将结果返回给输出值。CALL语句的基本语法形式如下:

call sp_name([parameter[,...]]);

  
 
  • 1

其中,sp_name是存储过程的名称;parameter是指存储过程的参数。

下面定义一个存储过程,然后调用这个存储过程。代码执行如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
由上面的代码看出,使用call语句来调用存储过程;使用select语句来查询存储过程的输出值。

2、调用存储函数

在MySQL中,存储函数的使用方法与MySQL内部函数的使用方法是一样的。换言之,用户自己定义的存储函数与MySQL内部函数是一个性质的。区别在于,存储函数是用户自己定义的,而内部函数是MySQL的开发者定义的。

下面定义一个存储函数,然后调用这个存储函数。代码执行如下:

在这里插入图片描述
在这里插入图片描述

上述存储函数的作用是根据输入的emp_id值到employee表中查询记录。查询出num字段的值等于emp_id的记录。然后将该记录的name字段的值返回。

三、查看存储过程和函数

存储过程和函数创建以后,用户可以查看存储过程和函数的状态和定义。用户可以通过show status语句来查看存储过程和函数的状态,也可以通过show create语句来查看存储过程和函数的定义。用户也可以通过查询information_schema数据库下的Routines表来查看存储过程和函数的信息。

1、show status语句查看存储过程和函数的状态

MySQL中可以通过show status语句查看存储过程和函数的状态。其基本语法形式如下:

show {procedure | function} status [like 'pattern'];

  
 
  • 1

其中,procedure参数表示查询存储过程;function参数表示查询存储函数;like‘pattern’参数用来匹配存储过程或函数的名称。

下面查询名为num_from_employee的存储过程的状态。代码执行如下:

在这里插入图片描述

2、show create语句查看存储过程和函数的定义

MySQL中可以通过SHOW CREATE语句查看存储过程和函数的状态。其基本语法形式如下:

show create {procedure | function} sp_name;

  
 
  • 1

其中,procedure参数表示查询的存储过程;function参数表示查询的存储函数;sp_name参数表示存储过程或函数的名称。

下面查询名为num_from_employee的存储过程的状态。代码执行如下:

在这里插入图片描述

3、从information_schema.routines表中查看存储过程和函数的信息

存储过程和函数的信息存储在information_schema数据库下的routines表中。可以通过查询该表的记录来查询存储过程和函数的信息。其基本语法形式如下:

select * from information_schema.routines where routine_name=''sp_name;

  
 
  • 1

其中,routine_name字段中存储的是存储过程和函数的名称;sp_name参数表示存储过程或函数的名称。

下面从routines表中查询名为num_from_employee的存储过程的信息。代码执行如下:

在这里插入图片描述

四、修改存储过程和函数

修改存储过程和函数是指修改已经定义好的存储过程和函数。MySQL中通过alter procedure语句来修改存储过程。通过alter runction语句来修改存储函数。

mysql中修改存储过程和函数的语句的语法形式如下:

alter {procedure | function } sp_name [characteristic ...]
characteristic:
	{contains sql | no sql | reads sql data | modifies sql data}
	| sql security {definer | invoker}
	| comment ‘string’

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

其中,sp_name参数表示存储过程或函数的名称;characteristic参数指定存储函数的特性。contains sql表示子程序包含sql语句,但不包含读或写的数据的语句;no sql表示子程序中不包含sql语句;reads sql data表示子程序中包含读数据的语句;modifies sql data表示子程序中包含写数据的语句。sql security {definer | invoker}指明谁有权限来执行。definer表示只有定义者自己才能够执行;invoker表示调用者可以执行。comment 'string’是注释信息。

下面修改存储过程num_from_employee的定义。将读写权限改为modifies sql data,并指明调用者可以执行。代码执行如下:

alter procedure num_from_employee
	modifies sql data
	sql security invoker;

  
 
  • 1
  • 2
  • 3

在这里插入图片描述

五、删除存储过程和函数

删除存储过程和函数指删除数据库中已经存在的存储过程和函数。MySQL中使用drop procedure语句来删除存储过程。通过drop function语句来删除存储函数。其基本形式如下:

drop {procedure | function } sp_name;

  
 
  • 1

其中,sp_name参数表示存储过程或函数的名称。

下面删除存储过程num_from_employee和存储函数name_from_empl-oyee。删除存储过程num_from_employee的代码如下:

drop procedure num_ from_employee;

  
 
  • 1

删除存储函数name_from_employee的代码如下:

drop function name_from_employee;

  
 
  • 1

在这里插入图片描述

六、总结

这里的相关内容还没有整理完毕,文章后面持续更新,建议收藏。

文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。

可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

文章来源: xiaoqijava.blog.csdn.net,作者:旷世奇才李先生,版权归原作者所有,如需转载,请联系作者。

原文链接:xiaoqijava.blog.csdn.net/article/details/126861880

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。