🍁一、 简介
🍃 1.1 原理
我们常用的操作数据库语言 SQL 语句在执行的时候需要要先编译,然后执行,
而存储过程(Stored Procedure)是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它
🍃 1.2 优点
(1).存储过程增强了 SQL 语言的功能和灵活性。
(2).存储过程允许标准组件是编程。
(3).存储过程能实现较快的执行速度。
(4).存储过程能过减少网络流量。
(5).存储过程可被作为一种安全机制来充分利用。
MySQL 5.0 终于开始已经支持存储过程,这样即可以大大提高数据库的处理速度,
同时也可以提高数据库编程的灵活性。
🍁 二、使用
🍃 2.1 常用命令
##删除
drop PROCEDURE pro_count_mysql
##创建
CREATE PROCEDURE pro_count_mysql(OUT P_o_cnt int)
BEGIN
SELECT COUNT(*) INTO P_o_cnt FROM mysql.user;
END;
##调用,给一个变量
call pro_count_mysql(@s);
##查询变量
mysql> select @s;
##数据字典
mysql> SHOW CREATE PROCEDURE proc6;
mysql> SHOW PROCEDURE STATUS --列出所有的存储过程
mysql> show procedure status where db=‘mes_db’;
注:部分版本mysql初始化不允许建存储过程,需要做如下设置
SET GLOBAL log_bin_trust_function_creators = 1;
🍃 2.2 变量定义
#外部变量
mysql> set @p1=‘IT邦德’;
mysql> select @p1;
内部定义变量用declare,如下所示
🍃 2.3 参数
in 参数
DELIMITER // CREATE PROCEDURE demo_in_parameter(IN p_in int) BEGIN SELECT p_in; SET p_in=2; SELECT p_in; END; // DELIMITER ; ##调用,给一个变量,不影响外面参数的值 call demo_in_parameter(3); MySQL [db1]> set @p_in=66; MySQL [db1]> call demo_in_parameter(@p_in); 注意:CMD窗口执行,记得留意空格
inout 参数
##CMD创建 DELIMITER // CREATE PROCEDURE demo_inout_parameter(INOUT p_inout int) BEGIN SELECT p_inout; SET p_inout=2; SELECT p_inout; END; // DELIMITER ; ##调用,影响外面传参的值 mysql> SET @p_inout=1; mysql> CALL demo_inout_parameter(@p_inout);
🍁 三、实战案例
🍃 3.1 条件语句
mysql> create table t1(id int);
##case 语句 DELIMITER // CREATE PROCEDURE proc3 (in parameter int) begin declare var int; set var=parameter+1; case var when 0 then insert into t values(17); when 1 then insert into t values(18); else insert into t values(19); end case; end; // DELIMITER ;
🍃 3.2 循环语句
mysql> create table t2(id int);
##repeat···· end repeat,它在执行操作后检查结果 DELIMITER // CREATE PROCEDURE proc5 () begin declare v int; set v=0; repeat insert into t values(v); set v=v+1; until v>=5 end repeat; end; // DELIMITER ; mysql> call proc5; mysql> select * from t2;
🍃 3.3 动态生成表
##学生表
select * from tb_student
##成绩表
select * from tb_score
选课表
select * from tb_course
编写一个存储过程,
要求对每门已选课程生成成绩表,表名为课程名,成绩表的字段包括学号、姓名、班级、成绩。
如果能独立完成,证明你的数据库应用能力已经跃上了一个台阶
DROP PROCEDURE create_table_pro; DELIMITER // CREATE PROCEDURE create_table_pro() BEGIN # 定义接受sql数据的变量 DECLARE courseNo varchar(50); DECLARE studentNo varchar(20); DECLARE studentName varchar(20); DECLARE classNo varchar(20); DECLARE score int; # 声明表名称 DECLARE tblname VARCHAR(32); # 总行数 DECLARE cnt INT DEFAULT 0; # 循环变量i DECLARE i INT DEFAULT 0; declare tmp_cursor cursor for( select c.courseNo, a.studentNo, a.studentName, a.classNo, b.score from tb_student a,tb_score b,tb_course c where a.studentNo = b.studentNo and b.courseNo = c.courseNo order by 1); SELECT COUNT(*) INTO cnt from tb_student a,tb_score b,tb_course c where a.studentNo = b.studentNo and b.courseNo = c.courseNo; open tmp_cursor; # 开始循环 REPEAT SET i := i+1; FETCH tmp_cursor INTO courseNo,studentNo,studentName,classNo,score; SET tblname = CONCAT('course_',courseNo); SET @delTabl = CONCAT('DELETE FROM ',tblname,' WHERE studentNo=','''',studentNo,''''); SET @createTbsql = CONCAT('create table if not exists ',tblname,'(studentNo char(10) not null primary key, studentName varchar(10) not null,classNo char(6),credite int) ENGINE=InnoDB DEFAULT CHARSET=GB2312;'); SET @insertTabl = CONCAT(' insert into ',tblname,' values(', '''',studentNo,'''','\,', '''',studentName,'''','\,', '''',classNo,'''','\,', '''',score,'''', ')' ); select @insertTabl; # 执行动态删除表语句 PREPARE temp FROM @delTabl; EXECUTE temp; DEALLOCATE PREPARE temp; # 执行动态生成的创建表语句 PREPARE temp FROM @createTbsql; EXECUTE temp; DEALLOCATE PREPARE temp; # 执行动态表插入语句 PREPARE temp FROM @insertTabl; EXECUTE temp; DEALLOCATE PREPARE temp; UNTIL i>=cnt END REPEAT; # 循环结束 close tmp_cursor; END; // DELIMITER ;