MySQL中存储过程使用详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL中存储过程使用详解

【1】存储过程简介

我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行。而存储过程(StoredProcedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

一个存储过程是一个可编程的函数(存储过程无返回值),它在数据库中创建并保存,它由SQL语句和一些特殊的控制结构组成。

存储过程增强了SQL语言的功能和灵活性

存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

存储过程允许标准组件是编程

存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

存储过程能实现较快的执行速度

如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。

因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。

而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。

存储过程能过减少网络流量

针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程。

那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。

存储过程可被作为一种安全机制来充分利用

系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。

【2】MySQL存储过程的创建

① 语法格式

MySQL存储过程创建的格式:CREATE PROCEDURE 过程名([过程参数[,...]])[特性 ...]过程体

# //为自定义符号,你可以换成其他,如`$$`。
//windows- DOS下
mysql> DELIMITER //   
mysql> CREATE PROCEDURE proc1(OUT s int)   
 -> BEGIN   
 -> SELECT COUNT(*) INTO s FROM user;   
 -> END   
 -> //   
mysql> DELIMITER ;   

这里需要注意的是DELIMITER // 和 DELIMITER ; 两句(一定注意delimiter与// 或者 ; 之间有空格!),DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错。

所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原(delimiter ;)。


存储过程根据需要可能会有输入、输出、输入输出参数,这里有一个输出参数s,类型是int型,如果有多个参数用","分割开。


过程体的开始与结束使用BEGIN与END进行标识。


② 声明分割符

如果是用MySQL的管理工具(如navicat for mysql or sqlyog)时,可以直接创建,不再需要声明。

如下,在navicat 创建 存储过程:

CREATE  PROCEDURE `pinout`(INOUT `pinout` int)
BEGIN
  #Routine body goes here...
  IF pinout = 0 THEN
    SELECT COUNT(*) FROM c_user  into pinout;
  ELSE
    set pinout = -1;
  END IF;
END

③ 参数

MySQL存储过程的参数用在存储过程的定义,共有三种参数类型:IN,OUT,INOUT,形式如:

CREATE PROCEDURE([[IN |OUT |INOUT ]参数名数据类形...])
IN-输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值;
OUT-输出参数:该值可在存储过程内部被改变,并可返回;
INOUT-输入输出参数:调用时指定,并且可被改变和返回 。

【3】变量

① 局部变量

需在过程体前声明局部变量,作用范围在begin end 之间。

DECLARE  variable_name [,variable_name...]  datatype  [DEFAULT value];

其中,datatype为MySQL的数据类型,如:int, float, date,varchar(length)

示例如下:

DECLARE l_int  int  unsigned  default  4000000; 
DECLARE l_numeric  number(8,2)  DEFAULT  9.95; 
DECLARE l_date  date  DEFAULT  '1999-12-31'; 
DECLARE l_datetime  datetime  DEFAULT  '1999-12-31 23:59:59'; 
DECLARE l_varchar  varchar(255)  DEFAULT  'This will not be padded';  

变量赋值

SET 变量名=表达式值[,variable_name = expression...]

示例如下:

//存储过程中
begin
  ...//
  set number = 10; -- 为变量赋值
  select number; -- 获取变量值
end

② 用户变量

用户变量名一般以@开头 ;用户变量作用域范围为当前客户端。即,可在存储过程外部查看该用户变量。

  • @param形式;
  • set定义和赋值;
  • 作用域范围为全局;
  • 用户变量名对大小写不敏感。

设置用户变量的一个途径是执行SET语句:

SET @var_name = expr [, @var_name = expr] ...
对于SET,可以使用 = 或 := 作为赋值符号。
分配给每个变量的expr可以为整数、实数、字符串或者NULL值。

可以先在用户变量中保存值然后在以后引用它,这样可以将值从一个语句传递到另一个语句。

用户变量与连接有关(会话级别)。

也就是说,一个客户端定义的变量不能被其它客户端看到或使用。当客户端退出时,该客户端连接的所有变量将自动释放。

//navicat for mysql 工具中
set @number =10; -- 为变量赋值
select @number; -- 获取变量值
-- 或者
select 'hello' into @A;
select @A;

d76139b667a9558a4d59bb9493f2ecdd.png

也可以在存储过程中使用用户变量 用户变量为会话级别,当次连接有效

CREATE PROCEDURE GreetWorld( ) 
begin
SELECT CONCAT(@greeting,' World');
end 
--- 测试如下
SET @greeting='Hello';
CALL GreetWorld(); 

需要注意的是,用户变量尽量提前赋值(默认为null),且在本次链接中有效(一般不在存储过程中使用用户变量,而是使用参数传入)。


存储过程内部使用变量,无论是局部变量或用户变量,尽量赋初值。

【4】存储过程查看

查看数据库中创建的存储过程,有如下几种方式:

① show procedure status where db='数据库名';
② select routine_name from information_schema.routines where routine_schema='数据库名';
③ select name from mysql.proc where db=’数据库名’;
④  show procedure status; --查看所有存储过程
⑤ show procedure status like pattern;--模糊查询

查看存储过程创建语句

可以像查看表创建语句一样查看存储过程创建详细:

# 当前数据库下查询不需要数据库名
SHOW CREATE PROCEDURE [数据库.]存储过程名; 

68f20ac16d0896d1813412da63838e45.png


【5】修改存储过程

使用ALTER语句可以修改存储过程或函数的特性,只能修改特性。如果想修改过程体只能删除存储过程再重新创建。

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

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...] 
characteristic: 
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } 
| SQL SECURITY { DEFINER | INVOKER } 
| COMMENT 'string'

其中释义如下:

① sp_name参数表示存储过程或函数的名称;

② characteristic参数指定存储函数的特性。

  • ③ CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
  • ④ NO SQL表示子程序中不包含SQL语句;
  • ⑤ READS SQL DATA表示子程序中包含读数据的语句;
  • ⑥ MODIFIES SQL DATA表示子程序中包含写数据的语句。

⑦ SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行。

  • ⑧ DEFINER表示只有定义者自己才能够执行;
  • ⑨ INVOKER表示调用者可以执行;

⑩ COMMENT 'string’是注释信息。

说明: 修改存储过程使用ALTER PROCEDURE语句,修改函数使用ALTER FUNCTION语句。

但是,这两个语句的结构是一样的,语句中的所有参数都是一样的。而且,它们与创建存储过程或函数的语句中的参数也是基本一样的。

测试如下:

ALTER PROCEDURE proc1 
SQL SECURITY INVOKER;
-- 指明调用者可以执行

查询结果状态:

SELECT SPECIFIC_NAME,SQL_DATA_ACCESS,
SECURITY_TYPE FROM 
information_schema.Routines WHERE ROUTINE_NAME='proc1' ;

48dd62fc5e58df8efb2d530b819a7758.png

【6】删除存储过程

删除一个存储过程比较简单,和删除表一样:

DROP PROCEDURE procName ;-- 删除存储过程
drop table table_name;-- 删除表
drop view view_name; -- 删除视图
drop database name;-- 删除数据库
drop function name;-- 删除函数
drop trigger name;-- 删除触发器


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
存储 SQL NoSQL
|
3月前
|
存储 SQL 关系型数据库
MySql数据库---存储过程
MySql数据库---存储过程
51 5
|
3月前
|
存储 关系型数据库 MySQL
MySQL 存储过程返回更新前记录
MySQL 存储过程返回更新前记录
79 3
|
3月前
|
存储 SQL 关系型数据库
MySQL 存储过程错误信息不打印在控制台
MySQL 存储过程错误信息不打印在控制台
91 1
|
5月前
|
存储 关系型数据库 MySQL
Mysql表结构同步存储过程(适用于模版表)
Mysql表结构同步存储过程(适用于模版表)
57 0
|
5月前
|
存储 SQL 关系型数据库
MySQL 创建存储过程注意项
MySQL 创建存储过程注意项
59 0
|
6月前
|
存储 SQL 关系型数据库
(十四)全解MySQL之各方位事无巨细的剖析存储过程与触发器!
前面的MySQL系列章节中,一直在反复讲述MySQL一些偏理论、底层的知识,很少有涉及到实用技巧的分享,而在本章中则会阐述MySQL一个特别实用的功能,即MySQL的存储过程和触发器。
124 0
|
6月前
|
存储 SQL 数据库
MySQL设计规约问题之为什么要避免使用存储过程、触发器和函数
MySQL设计规约问题之为什么要避免使用存储过程、触发器和函数
|
7月前
|
存储 SQL 关系型数据库
MySQL数据库进阶第四篇(视图/存储过程/触发器)
MySQL数据库进阶第四篇(视图/存储过程/触发器)
|
7月前
|
存储 SQL 关系型数据库
MySQL存储过程和存储函数的使用
MySQL的存储过程和存储函数在功能和用法上有明显的区别。存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,通过指定名称和参数(如果有)来调用执行,可以返回多个值或结果集,但不直接返回值。而存储函数则是一个有返回值的特殊存储过程,它返回一个值或表对象,可以直接嵌入SQL语句中使用,如SELECT语句中。两者都是为了提高SQL代码的重用性和性能,但使用场景和方式有所不同。
4331 4