6、存储过程与存储函数
作者:互联网
存储过程(Stored Procedure)
多条 SQL 语句处理多个表,存储过程是一组为了完成特定功能的 SQL 语句集合。
一组经过预先编译的SQL语句的封装,调用者无需考虑逻辑功能的具体实现过程,它可以被 Java 和 C# 等调用。
使用存储过程的目的是将常用或复杂的工作预先用 SQL 语句写好并用一个指定名称存储起来,这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。
优点
- 简化操作,提高了sql语句的重用性
- 减少操作过程中的失误,提高效率
- 减少编译次数,减少和数据库连接次数
- 减少网络传输量(客户端不需要把所有的 SQL 语句通过网络发给服务器)
- 减少了 SQL 语句暴露在网上的风险,也提高了数据查询的安全性
创建使用
- 可以使用 CREATE PROCEDURE 语句创建存储过程。
- 语法格式如下:
DELIMITER 新的结束标记 CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名 参数类型,...)[characteristics ...] BEGIN 存储过程体 END 新的结束标记 DELIMITER ;
- 没有参数(无参数无返回);仅仅带 IN 类型(有参数无返回)
- 仅仅带 OUT 类型(无参数有返回);既带 IN 又带 OUT(有参数有返回)
- 带 INOUT(有参数有返回)。IN、OUT、INOUT 都可以在一个存储过程中带多个。
- 存储过程体中间包含了多条 SQL 语句,每个语句都以(;)号为结束符。DECLARE:用来声明变量,使用的位置在于 BEGIN…END 语句中间,而且需要在其他语句使用之前进行变量的声明。
- 如果仅仅一条SQL 语句,则可以省略 BEGIN 和 END
- SET:赋值语句,用于对变量进行赋值。
- SELECT… INTO:把从数据表中查询的结果存放到变量中,也就是为变量赋值。
- 需要设置新的结束标记:DELIMITER 新的结束标记
- 因为MySQL默认的语句结束符号为分号';'。为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符。
- 存储过程定义完毕之后再使用“DELIMITER ;”恢复默认结束符。
- 当使用DELIMITER命令时,应该避免使用反斜杠(‘\’)字符,因为反斜线是MySQL的转义字符。
示例1:无参数的存储过程
-- 创建测试表 CREATE TABLE test (tid int); -- 删除存储过程 DROP PROCEDURE p1; DROP PROCEDURE p2; DROP PROCEDURE p3;
- 批量插入
-- 示例1:无参数的存储过程. -- 创建存储过程 CREATE PROCEDURE p1 () BEGIN #声明局部变量 DECLARE i INT DEFAULT 1; #循环 WHILE i<=10 DO #循环体 往test表批量插入数据 INSERT INTO test (tid) VALUES (i); #改变循环条件 SET i=i+1; END WHILE; -- 查看test表数据 SELECT*from test; END; -- 调用存储过程 CALL p1 ();
- Loop
-- 创建存储过程 CREATE PROCEDURE p2() BEGIN #声明局部变量 DECLARE i INT DEFAULT 1; #循环 lp : LOOP #循环体 往test表批量插入数据 INSERT INTO test (tid) VALUES (i); #改变循环条件 SET i=i+1; #条件语句判断循环结束条件 IF i>10 THEN LEAVE lp; #退出循环 END IF; END LOOP; -- 查看test表数据 SELECT * from test; END; -- 调用存储过程 CALL p2 ();
- Repeat
-- 创建存储过程 CREATE PROCEDURE p3() BEGIN #声明局部变量 DECLARE i INT DEFAULT 1; #循环 REPEAT #循环体 往test表批量插入数据 INSERT INTO test (tid) VALUES ( i); #改变循环条件 SET i=i+1; #退出循环 UNTIL i>10 END REPEAT; -- 查看test表数据 SELECT * from test; END; -- 调用存储过程 CALL p3 ();
示例2:有in和out参数的存储过程
- 练习:根据账户编号,返回账户余额,用户等级。
- -- 余额>=2000,显示用户等级'砖石会员-- 余额>=1500,显示用户等级'铂金会员'
- -- 余额>=1000,显示用户等级'黄金会员-- 余额>=500,显示用户等级'大众会员'
-- 创建存储过程 DROP PROCEDURE p4; create procedure p4( IN in_account_id varchar(36), OUT out_balance decimal, -- 十进制 OUT out_level varchar(20) ) BEGIN SELECT balance, CASE WHEN balance>=2000 THEN '钻石会员' WHEN balance>=1500 THEN '铂金会员' WHEN balance>=1000 THEN '黄金会员' WHEN balance>=500 THEN '大众会员' ELSE '普通会员' END AS balance_level INTO out_balance,out_level from account where account_id=in_account_id; END; SET @in_account_id='aec8301d-ab3b-11ec-b6ed-0a0027000018'; -- account 表中有的数据 CALL p4(@in_account_id,@out_balance,@out_level); -- 调用 SELECT @out_balance,@out_level; -- select输出出参
调用存储过程
- 存储过程有多种调用方法。存储过程必须使用CALL语句调用,并且存储过程和数据库相关,如果要执行其他数据库中的存储过程,需要指定数据库名称。
CALL 存储过程名(实参列表) -- 1. 调用in模式的参数: CALL 存储过程名('值'); -- 2. 调用out模式的参数: SET @name; CALL 存储过程名(@name); SELECT @name; -- 3. 调用inout模式的参数: SET @name=值; CALL 存储过程名(@name); SELECT @name;
删除
DROP PROCEDURE [IF EXISTS] 存储过程的名;
存储函数
创建
DELIMITER 新的结束标记 CREATE FUNCTION 函数名(参数名 参数类型,...) RETURNS 返回值类型 [characteristics ...] BEGIN 函数体 RETURN 语句 END 新的结束标记 DELIMITER ;
- 参数列表:指定参数为IN、OUT或INOUT只对PROCEDURE是合法的,FUNCTION中总是默认为IN参数。
- RETURNS type 语句表示函数返回数据的类型;
- RETURNS子句只能对FUNCTION做指定,对函数而言这是
强制
的。 - 它用来指定函数的返回类型,而且函数体必须包含一个
RETURN value
语句。
- RETURNS子句只能对FUNCTION做指定,对函数而言这是
- characteristic 创建函数时指定的对函数的约束。
- 函数体也可以用BEGIN…END来表示SQL代码的开始和结束。如果函数体只有一条语句,也可以省略BEGIN…END。
调用存储函数
SELECT 函数名(实参列表)
删除
DROP FUNCTION [IF EXISTS] 存储函数的名;
对比存储函数和存储过程
关键字 | 调用语法 | 返回值 | 应用场景 | |
---|---|---|---|---|
存储过程 | PROCEDURE | CALL 存储过程() | 理解为有0个或多个 | 一般用于更新 |
存储函数 | FUNCTION | SELECT 函数() | 只能是一个 | 一般用于查询结果为一个值并返回时 |
此外,存储函数可以放在查询语句中使用,存储过程不行。反之,存储过程的功能更加强大,包括能够执行对表的操作(比如创建表,删除表等)和事务操作,这些功能是存储函数不具备的。
标签:语句,存储,END,函数,--,过程,PROCEDURE 来源: https://www.cnblogs.com/seventeen9588/p/16050035.html