一、定义
存储过程(Stored Procedure)简单来讲就是一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
注意:
1.大家可以使用MySQL命令创建学习,这里我使用sqlyog工具进行讲解。
2.对于初学者来说刚接触不知道在哪里创建存储语句,以sqlyog为例,打开数据 库就能看到存储过程的文件夹,在此文件夹上创建存储过程即可,至于怎么调用,下面听我一一道来。
3.在一个存储过程中可以调用另一个存储过程,但不能删除另一个存储过程。
二、基本语法
1. 创建存储过程
drop procedure if exists proName; ---proName存储过程名,如果存在则删除
delimiter // ---这个‘//’是用户定义的结束符,通常这个符号可以是一些特殊的符号,如两个“?”或两个“$$”等。
create procedure proName() ---procedure创建存储过程的关键字 proName存储过程名
begin
... ---SQL代码(一般放在begin和end之间)
end // ---end代码SQL语句结束了,//代表整个过程结束了
delimiter ; ---上面我自己定义了结束符//,以后都变成了//,如果希望换回默认的分号“;”作为结束标志,则添加上这句
2. 调用存储过程
call proName() ---不管有没有参数,()都要有,关键字call
3. 删除存储过程
drop procedure proName;
4. 查询有哪些存储过程
SHOW PROCEDURE STATUS; ---如果要模糊查询可以加上 LIKE 'x%'
三、实例
首先创建一个user表,包含字段uid,username,age,sex
CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`username` varchar(255) DEFAULT NULL COMMENT '用户名称',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`sex` char(1) DEFAULT NULL COMMENT '性别',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `user`(`uid`,`username`,`age`,`sex`) values (1,'张三',20,'男'),(2,'李四',18,'女');
1. select查询存储过程
通过uid查询用户信息
DELIMITER $$
CREATE PROCEDURE `demo`.`selectTest1`(IN u_uid INT(11),OUT u_username VARCHAR(255),OUT u_age INT(11),OUT u_sex CHAR) ----demo为数据库名称,参数:IN表示输入参数,out表示输出参数,INOUT表示可以是输入参数也可以是输出参数;u_username传入参数的形参,注意这里要和数据库的字段区别开来,后面是该字段的数据类型,细心的盆友应该已经发现这里和java语法刚好相反,
BEGIN
SELECT username,age,sex INTO u_username,u_age,u_sex FROM `user` WHERE uid=u_uid; ---这里的into表示将数据库中的数据查询出来赋值给输出的参数
END $$
DELIMITER ;
CALL selectTest1(1,@name,@age,@sex); ---调用存储过程,其中@表示用户定义的临时变量,
SELECT @name,@age,@sex; ---查询数据
2. inserTest添加存储过程
DELIMITER $$
CREATE PROCEDURE `demo`.`inserTest`(IN u_username VARCHAR(255),IN u_age INT(11),IN u_sex CHAR)
BEGIN
INSERT INTO `user`(username,age,sex) VALUES(u_username,u_age,u_sex);
END$$
DELIMITER ;
CALL inserTest('老王',22,'男'); ---调用存储过程
3. updateTest更新存储过程
DELIMITER $$
CREATE PROCEDURE `demo`.`updateTest`(IN u_uid INT(11),IN u_username VARCHAR(255))
BEGIN
UPDATE `user` SET username=u_username WHERE uid=u_uid;
END$$
DELIMITER ;
CALL updateTest(3,'王五1'); ---调用存储过程
4. deleteTest删除存储过程
DELIMITER $$
CREATE PROCEDURE `demo`.`deleteTest`(in u_uid int(11))
BEGIN
delete from `user` where uid=u_uid;
END$$
DELIMITER ;
call deleteTest(3);
四、定义变量
如果希望MySQL执行批量插入的操作,那么至少要有一个计数器来计算当前插入的是第几次。
这里的变量是用在存储过程中的SQL语句中的,变量的作用范围在BEGIN … END 中。
没有DEFAULT子句,初始值为NULL。
DECLARE username,address VARCHAR; -- DECLARE 为定义变量的关键字,先定义熟悉在定义类型,相同数据类型可以这样定义
DECLARE age INT DEFAULT 20; -- 指定默认值。若没有DEFAULT子句,初始值为NULL。
为变量赋值
SET username= '小李'; -- 为username变量设置值
五、使用变量实例
DELIMITER $$
CREATE PROCEDURE `demo`.`selectTest2`(OUT sumNum INT(11))
BEGIN
DECLARE num INT; ---定义num变量
SET num=0; ---给变量赋值
SELECT COUNT(1) INTO num FROM `user`;
SET sumNum=num; ---给变量赋值
END$$
DELIMITER ;
CALL selectTest2(@sumNum);
六、流程控制
- IF–then–else(相当于if-else if-else)条件语句使用
DELIMITER $$
CREATE PROCEDURE `demo`.`demoIF`(OUT u_username VARCHAR(255))
BEGIN
DECLARE u_uid INT DEFAULT 0; ---定义变量并赋值
IF u_uid = 1 ---判断如果u_uid=1,注意此处不能加上‘;’
THEN SET u_username='是张三';---如果条件成立,则走then语句
ELSE SET u_username='不是张三';---否则走这
END IF; ---不要忘了要结束if语句
END$$
DELIMITER ;
CALL demoIF(@u_username);
SELECT @u_username;
2. CASE–when–else(相当于switch–case–default)语句使用
DELIMITER $$
CREATE PROCEDURE `demo`.`demoCase`(IN num INT(11),OUT result VARCHAR(255))
BEGIN
CASE num ---判断num值和下面哪个when里面的值相等,相等则进行赋值,都不相等则执行else块,注意不能写‘;’
WHEN 0 THEN SET result='000';
WHEN 1 THEN SET result='111';
WHEN 2 THEN SET result='222';
ELSE SET result='666';
END CASE; ---使用完case要结束;
END$$
DELIMITER ;
CALL demoCase(4,@result);
3. LOOP(相当于for)语句使用,重复执行SQL,LEAVE 用于退出循环
DELIMITER $$
CREATE PROCEDURE `demo`.`demoLoop`(OUT result VARCHAR(255))
---一个批量插入数据
BEGIN
DECLARE num INT DEFAULT 0;
add_loop:LOOP ---相当于forEach循环
SET num = num+1; ---变量自增
IF num > 3 ---如果num>3
THEN LEAVE add_loop;---则跳出循环
ELSE ---否则,执行添加数据操作
INSERT INTO `user`(username,age,sex) VALUES("小红",23,'女');
END IF; ---结束if
SET result=num;
END LOOP; ----结束loop
END$$
DELIMITER ;
CALL demoLoop(@result);
4. WHILE–DO语句的使用
DELIMITER $$
CREATE PROCEDURE `demo`.`demoWhile`(IN indexNum INT(11),OUT result VARCHAR(255))
BEGIN
DECLARE num INT DEFAULT 0;
WHILE num < indexNum
DO
SET num = num+1;
INSERT INTO `user`(username,age,sex) VALUES("mimi",23,'男');
END WHILE;
SET result=num;
END$$
DELIMITER ;
CALL demoWhile(5,@result);