SQL命令 --> MySQL引擎首先对于我们输入的SQL命令进行语法分析,来看一下我们输入的语句是否 -->语法正确 --> 编译,成MySQL引擎可识别命令 -->执行,并将-->执行结果-->返回给客户端。
如果我们省略其中语法分析和编译的环节,MySQL的执行效率就会提高。
【存储过程】是SQL语句和控制语句的预编译集合,以一个名称存储并作为一个单元处理;
存储过程存储在数据库内,可以有应用程序调用执行,且允许用户进行声明变量以及及进行流程控制;
存储过程可以接受参数,可以接受输入、输出类型的参数,并且可以存在多个返回值。
【存储过程的优点】:1. 增强了SQL语句的功能和灵活性: 存储过程内可以写控制语句,具有很强的灵活性、可以完成复杂的判断等;
2. 实现了较快的执行速度: 如果某一个操作包含大量的SQL语句,这些语句都将被MySQL引擎执行语法分析、编译、执行,效率相对较低;
而存储过程是预编译的,当客户端第一次调用此存储过程时,MySQL引擎将对其进行语法分析、编译等操作,然后将此编译结果存储到内存当中,以后客户端再次调用此存储过程时便直接从内存当中执行,效率较高,速度较快
3. 减少网络流量: 如果我们通过客户端每个单独发送SQL语句让服务器执行的话,通过HTTP协议提交的数据量相对较大;
而应用存储过程,我们只需要传递存储过程的名字、需要的数值就可以了,提交给服务器的数据量相对较小。
【创建存储过程】:
CREATE
[DEFINER = { user | CURRENT_USER }] 创建者, 默认当前登录到MySQL客户端的用户
PROCEDURE sp_name ([proc_parameter[,...]]) 存储过程的名字,可以有0~多个参数
[characteristic ...] routine_body 特性 (与自定义函数相同), 过程体
proc_parameter:
[ IN | OUT | INOUT ] param_name type
[参数]:
IN :表示该参数的值必须在调用存储过程时指定;
OUT:表示该参数的值可以被存储过程中的代码改变,并且可以返回;
INOUT:表示该参数在调用时指定,并且可以被存储过程的过程体改变和返回给调用者。
[特性]:
COMMENT ‘string‘
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
其中:
COMMENT : 注释
CONTAINS SQL : 包含SQL语句,但不包含读或写数据的语句
NO SQL : 不包含SQL语句
READS SQL DATA : 包含读数据的语句
MODIFIES SQL DATA : 包含写数据的语句
SQL SECURITY { DEFINER | INVOKER } : 指明谁有权限来执行
[过程体]:
过程体由合法的SQL语句构成;
可以是"任意"(对于记录的增、删、改、查、多表连接操作)SQL语句 (我们不可能通过存储过程创建数据表,也不可能通过存储过程创建数据库);
过程体如果为复合结构(超过了两个以上的语句)则使用BEGIN...END语句;
复合结构语句内可以声明变量,可以使用流程控制语句(if 语句、when语句)以及while循环等。
【例1——创建没有参数的存储过程】:
【调用存储过程】 CALL sp_name([parameter[,...]]) 或者 CALL sp_name[()]
如果存储过程在封装时没有参数,那么()可以有也可以没有;如果存储过程封装过程中有参数,则()不能省略;
【例2——创建有IN类型参数的存储过程】:
假如我们从数据表中经常要删除记录 DELETE FROM tbl_name WHERE xxx,我们就可以将这个过程封装成一个存储过程:
!!!注意!!! 给参数的时候,参数的名字不能和数据表中的记录名相同,否则所有记录都会被删除。
【修改存储过程】 ALTER PROCEDURE sp_name [characteristic ...]
COMMENT ‘string‘
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA}
| SQL SECURITY { DEFINER | INVOKER}
上述方法只能修改注释、内容类型等,并不能修改过程体。
只能删除当前存储过程,再重建。
【删除存储过程】:DROP PROCEDURE [IF EXISTS] sp_name
正确创建方法如下:
【例3——创建有IN和OUT类型参数的存储过程】
从数据表中删除id不固定的记录,并且返回剩余的记录数:
@nums其实就是变量。变量也可以在BEGIN...END中声明。
区分: 通过DECLARE声明(该语句必须位于BEGIN..END块的第一行)的变量为局部变量,作用范围只在BEGIN..END语句块之间。
通过(SELECT... INTO或)SET @语句声明的变量我们称之为用户变量,跟MySQL的客户端绑定。通过这种方法声明的变量只对当前用户所使用的客户端生效。
【例4——创建有多个OUT类型参数的存储过程】
根据age字段删除用户,返回删除的用户数以及剩余的用户数:
SELECT ROW_COUNT(); 得到行数,准确地讲是得到插入、删除、更新的被影响到的记录总数
【存储过程与自定义函数的区别】:
1. 存储过程实现的功能要复杂一些;而函数的针对性更强: 一般,我们很少用函数对表做操作,但经常用存储过程对表做操作。
2. 存储过程可以返回多个值;而函数只能有一个返回值。
3. 存储过程一般独立的来执行(CALL sp_name...); 而函数主要是作为其他SQL语句的组成部分来出现(和内置的函数相同)。
实际应用中我们很少用函数,但是我们经常可以把复杂的过程封装成存储过程。
存储过程只能修改简单的特性,不能修改过程体。如果想修改过程体,只能先将存储过程删除再创建。