本文主要讲述了MySQL的函数和存储过程。
3.2函数&存储过程
3.2.1函数
declare 变量名 类型; # 定义变量
select id into 变量名 from table; # 将table表中的id列值赋给变量。
CREATE FUNCTION # 创建
Count_ voverdue(vloanno varchar(16) ,vbookno char(9)) # 函数
RETURNS INT # 返回啥
BEGIN
declare cnt tinyint;
declare term_v tinyint;
select cu.term into term_v from Class_User cu, Users u
where cu.classNo = u.classNo and u.loanNo = vloanno;
select datediff(now(), borrowDate) into cnt from Loan
where bookNo = vbookno and loanNo = vloanno;
if (cnt > term_v) then
return cnt - term_v;
else
return 0;
end if;
end;
3.2.2存储过程
存储过程,百度百科上是这样解释的,存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来调用存储过程。简单的说就是专门干一件事一段sql语句。
可以由数据库自己去调用,也可以由java程序去调用。
在oracle数据库中存储过程是procedure。为什么需要存储过程?
1.效率高
存储过程编译一次后,就会存到数据库,每次调用时都直接执行。而普通的sql语句我们要保存到其他地方(例如:记事本 上),都要先分析编译才会执行。所以想对而言存储过程效率更高。
2.降低网络流量
存储过程编译好会放在数据库,我们在远程调用时,不会传输大量的字符串类型的sql语句。
3.复用性高
存储过程往往是针对一个特定的功能编写的,当再需要完成这个特定的功能时,可以再次调用该存储过程。
4.可维护性高
当功能要求发生小的变化时,修改之前的存储过程比较容易,花费精力少。
5.安全性高
完成某个特定功能的存储过程一般只有特定的用户可以使用,具有使用身份限制,更安全。
存储过程有三种返回:
- 用return返回int型数据
- 用返回参数返回结果,可以返回各种数据类型(通过游标来循环查询结果每一行)
- 直接在存储过程中用select返回结果集,可以是任意的select语句,这意味着是任意的返回结果集
存储过程和触发器的区别:
1、存储过程可以采用输入参数,而触发器不可以;
2、存储过程可以返回零或n值,而触发器无法返回值;
3、存储过程中可以使用事务,而触发器不允许。
Delimited //
定义存储语句结束标识符 //
也可以换成$$
等其他符号
储存创建不返回值,调用用call,带入参数即可。有in 有out,默认in
**if(@@error<>0) then**
判断是否更新成功。
create or replace procedure 过程名 ([参数1,参数2,...])
as <过程化SQL块>;
''' 存储过程的参数有三种:
IN:输入参数,也是默认模式,表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回;
OUT:输出参数,该值可在存储过程内部被改变,并可返回;
INOUT:输入输出参数,调用时指定,并且可被改变和返回
'''
--【例】定义名称为proc_add的存储过程,该存储过程有两个int类型的参数,分别为a和b。
DELIMITER //
CREATE PROCEDURE proc_add(in a int, in b int)
BEGIN
DECLARE c int DEFAULT 0;
SET c = a + b;
SELECT c AS 'Result';
END //
DELIMITER ;
-- 调用上述存储过程
CALL proc_add(2,3);
> call out_param(@p_out) # out不接受输入参数
# 查询已经创建过的存储过程:
SHOW PROCEDURE STATUS WHERE db='数据库名';
# 查看存储过程的详细定义信息:
SHOW CREATE PROCEDURE 数据库.存储过程名;
# 删除
DROP PROCEDURE [IF EXISTS] 数据库名.存储过程名;
-- 从账户1转指定数额到账户2
create procedure transfer(inAccount int,outAccount int,amount float)
as declare
totalDepositOut float;
totalDepositIn float;
inAccountnum int;
begin
select total into totalDepositOut from Account where accountnum=outAccount;
if totalDepositOut is null then /*如果转出账户不存在,就回滚*/
rollback;
return;
end if;
if totalDepositOut < amount then /*如果账户余额不足*/
rollback;
return;
end if;
select Accountnum into inAccountnum from Account where accountnum=inAccount;
if inAccountnum is null then /*如果转入账户不存在*/
rollback;
return;
end if;
update Account set total=total-amount where accountnum=outAccount; /*修改转出账户余额*/
update Account set total=total+amount where accountnum=inAccount; /*修改转入账户余额*/
commit; /*提交事务*/
end;