BCSP-玄子JAVA开发之JAVA数据库编程CH-05_存储过程
5.1 存储过程
5.1.1 什么是存储过程
- Stored Procedure
- 是一组为了完成特定功能的SQL 语句集合
- 经编译后保存在数据库中
- 通过指定存储过程的名字并给出参数的值
- MySQL5.0版本开始支持存储过程,使数据库引擎更加灵活和强大
5.1.2 存储过程可以包含
- 可带参数,也可返回结果
- 可包含数据操纵语句、变量、逻辑控制语句等
5.1.3 存储过程的优缺点
优点
- 减少网络流量
- 提升执行速度
- 减少数据库连接次数
- 安全性高
- 复用性高
缺点
- 可移植性差
在实际应用开发中,要根据业务需求决定是否使用存储过程对于应用中特别复杂的数据处理,可以选用存储过程来进行实现例如:复杂的报表统计,涉及多条件多表的联合查询等
5.2 创建存储过程
CREATE
[DEFINER = { user | CURRENT_USER }]
# 定义DEFINER默认为当前用户
PROCEDURE 存储过程名
[SQL SECURITY { DEFINER | INVOKER } | …]
# 指定DEFINER或INVOKER权限
BEGIN
…
END
特性 | 说明 |
---|---|
LANGUAGE SQL | 表示存储过程语言,默认SQL |
{CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA} | 表示存储过程要做的工作类别默认值为CONTAINS SQL |
SQL SECURITY { DEFINER | INVOKER } | 指定存储过程的执行权限默认值是DEFINERDEFINDER:使用创建者的权限INVOKER:用执行者的权限 |
COMMENT ‘string’ | 存储过程的注释信息 |
如果省略SQL SECURITY特性,则使用DEFINER属性指定调用者,且调用者必须具有EXECUTE权限,必须在mysql.user表中如果将SQL SECURITY特性指定为INVOKER,则DEFINER属性无效
5.2.1 定义存储过程的参数
IN:指输入参数
- 该参数的值必须在调用存储过程时指定
- 存储过程中可以使用该参数,但它不能被返回
OUT:指输出参数
- 该参数可以在存储过程中发生改变,并可以返回
INOUT:指输入输出参数
- 该参数的值在调用存储过程时指定
- 在存储过程中可以被改变和返回
如果需要定义多个参数,需要使用
,
进行分隔
5.2.2 调用存储过程
CALL 存储过程名([参数1,参数2, …]);
# 根据存储过程的定义包含相应的参数
存储过程调用类似于Java中的方法调用
5.2.3 存储过程中的变量
与Java语言类似,定义存储过程时可以使用变量
DECLARE 变量名[,变量名...] 数据类型 [DEFAULT 值];
给变量进行赋值
SET 变量名 = 表达式值[,变量名=表达式...] ;
定义存储过程时,所有局部变量的声明一定要放在存储过程体的开始;否则,会提示语法错误
5.3 MySQL变量
系统变量
- 指MySQL全局变量,以“@@”开头,形式为“@@变量名”
用户自定义变量
- 局部变量
- 一般用于SQL的语句块中,如:存储过程中的BEGIN和END语句块
- 作用域仅限于定义该变量的语句块内
- 生命周期也仅限于该存储过程的调用期间
- 在存储过程执行到END时,局部变量就会被释放
- 会话变量
- 是服务器为每个客户端连接维护的变量,与MySQL客户端是绑定的
- 也称作用户变量
- 可以暂存值,并传递给同一连接中其他SQL语句进行使用
- 当MySQL客户端连接退出时,用户变量就会被释放
- 用户变量创建时,一般以“@”开头,形式为“@变量名”
5.3.1 演示案例
根据病人名称和检查项目ID输出最后一次检查时间
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_exam_GetLastExamDateByPatientNameAndDepID`(IN patient_name VARCHAR(50), IN dep_id INT,OUT last_exam_date DATETIME)
BEGIN
#Routine body goes here...
DECLARE patient_id INT; #声明局部变量
SELECT patientID INTO patient_id FROM patient WHERE patientName= patient_name;
SELECT patient_id; #输出病人的ID
SELECT MAX(examDate) INTO last_exam_date FROM prescription WHERE patientID = patient_id AND depID = dep_id;
END
SET @patient_name='夏颖';
SET @dep_id =1;
CALL proc_exam_GetLastExamDateByPatientNameAndDepID(@patient_name, @dep_id, @last);
SELECT @last;
BCSP-玄子JAVA开发之JAVA数据库编程CH-05_存储过程