存储过程概述
测试过程中,为满足某些前提条件(压力、容量测试),如何创造大批量的数据:
1.通过接口的方式批量造数据
2.开放脚本(JAVA、PHP、PYTHON等)进行批量造数据
3.使用工具(jmeter等)的mysql脚本发起批量造数据
4.通过mysql的存储过程造数据
接口方式
用户通过访问外部暴露的接口,将数据存储到数据库中。可通过人为的访问暴露的接口,将数据持续写进去
好处:通过简单的参数对应,访问后数据进入数据库,不用学习sql
坏处:不是每一个服务的接口都暴露在外面的
开放脚本/工具
编码语言(工具)方式持续访问(持续生成)sql,将数据库需要的内容造出来
好处:可以私人定制,随自己的想法去生产一些数据
坏处:需要对编码语言(工具)有一定学习
存储过程
事先经过编译并存储在数据库中的一段SQL语句的集合。简述就是数据库SQL语言层面的代码封装和重用
好处:速度很快,大量数据生成时间很短
坏处: 1、需要系统学习存储过程的语法
2、对于复杂的业务逻辑的存储过程变得很难
3、移植很差,跨数据库需重新创建
存储过程定义
存储过程的基本语句格式:
create procedure 数据库名.存储过程名([非必要内容,一般不填写*])
begin
[declare 变量名 类型 [default 值]]
存储过程的语句块;
end
数据库名:需要建立的数据库
存储过程名:创建的存储过程名称
*:可以不进行填写,相当于调用存储过程时,人为导入数值。
begin/end:存储过程的语句块放到这里,每次人为写的内容
存储过程使用
定义一个存储过程
create procedure `practice`.`demo`()
begin
select count(*) from student;
end;
简单的一个查询语句定义的存储过程,在这个存储过程中,查询语句变为存储过程的语句块,当存储过程语句运行后,在函数的下方就会出现一个名为demo的存储过程
调用存储过程
第一种:
在navicat中点击函数,找到demo这个函数,右键点击运行函数,就可以执行
第二种:
通过语句调用的方式调用:
call 存储过程名();
1.在库中右键点击查询,再查询语句中输入:
2.创建存储过程时,直接调用:
工作中使用最多的情景
创建多条数据,之前学的就无法完成这个需求,还需要继续学习下面的内容
需求:创建10条数据,不能单条单条创建
create procedure `practice`.`demo1`()
begin
declare i int;-- 声明变量
set i = 0; -- 初始化值为0
while(i<10)do -- 循环开始
INSERT INTO `practice`.`student` (`name`, `pwd`, `sex`, `birthday`, `address`, `email`) VALUES ('宋七', i, '男', '2000-02-17 10:19:15', '水里', NULL);
set i = i+1;
end while; -- 循环结束
end;
call demo1();
流程控制
控制存储过程的逻辑有:
if…else;case;while;repeat…until;loop
此处只举例while这种使用最多的逻辑方法,其余方法有使用场景在详细讨论
更进一步,当每次创建次数不定时,如何调用时可以自定义次数?
ifelse
if语句包含多个条件判断,根据结果为true,false执行,编程语言的ifelse语法类似
create procedure `demo`.`demo3`(in `day` int)
-- 存储过程体
begin
if `day` = 0 then
select '星期天';
elseif `day` = 1 then
select '星期一';
elseif `day` = 2 then
select '星期二';
else
select '无效日期';
end if;
end;
call demo3();
case
case是另一个条件判断的语句,mysql中有俩种语法格式
第一种:
create procedure `demo`.`demo4`(in `num` int)
-- 存储过程体
begin
case -- 条件开始
when `num`<0 then
select '负数';
when `num`>0 then
select '正数';
else
select '不是正数也不是负数';
end case;
end
第二种
create procedure `demo`.`demo5`(in `num` int)
-- 存储过程体
begin
case `num`-- 条件开始
when 0 then
select '负数';
when 1 then
select '正数';
else
select '不是正数也不是负数';
end case;
end
repeat…until
repeate。。untll语句的用法和java的do…while语句类似,先执行循环条件,在判断条件,区别是repeate表达式为false才执行循环操作,直到表达式为true停止
create procedure demo7(in num int,out SUM int)
begin
set SUM = 0;
repeat
set num = num+1;
set SUM = SUM+num;
until num >=2
end repeat;
end
call demo7(1,@sum);
select @sum;
loop
循环语句,用来重复执行某些语句,执行过程中可使用leave语句或者iterate来跳出循环,也可以嵌套if等判断语句
1.leave语句效果对于java中的break,用来终止循环
2.iterate语句相当于java中的continue,用来跳过此次循环,进入下一次循环,且iterate之下的语句将不再进行
create procedure demo8(in num int,out SUM int)
begin
set SUM = 0;
demo_sum:loop-- 循环开始
set num = num+1;
if num > 2 then
leave demo_sum; -- 结束此次循环
elseif num <=1 then
iterate demo_sum; -- 跳过此次循环
end if;
set SUM = SUM+num;
end loop demo_sum;-- 循环结束
end
call demo8(1,@sum);
select @sum;
升级版
create procedure demod(in s_name varchar(10),in s_sex char(1),out s_result varchar(20))
begin
-- 声明一个变量,用来决定这个名字是否存在
declare s_count int default 0;
-- 验证名称是否存在
select count(*) into s_count from student where `name` = s_name;
if s_count =0 then
INSERT INTO `practice`.`student` (`name`, `sex`) VALUES (s_name, s_sex);
set s_result = '数据添加成功';
else
set s_result = '名字已经存在,不能添加';
select s_result;
end if;
end
call demod("张三","男",@s_result)
此处就完成每次可以创建个人选中的次数
in:代表输入
num:变量名
int:变量类型
in:可以输入给存储过程的参数
out:可以从存储过程输出的参数
inout:可以输入、输出的参数
使用场景最多的为in
异常
1.[Err] 1304 - PROCEDURE demo2 already exists
2.[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘call demo2(5)’ at line 11
1.因为已经存在了demo2的存储过程,所以无法再次创建demo2的存储过程
解决方法:
先查询是否有叫demo2的存储过程,有的话就删除掉他
drop procedure if exists demo2; – 固定格式,只需要修改存储过程名称
2.sql语法有错误,检查;是否是英文状态
解决方法:
一般会告诉你在哪一行的附近,向这一句就在call demo2(5)的上面
简单经验
经验之谈:
1.在创建存储过程之前先检查是否存在,存在就删除掉
drop procedure if exists 存储过程名称;
2.每次使用存储过程创建大量数据时,建议将表删除后重新创建表,不知道怎么创建表,在库上面右键点击选择转储SQL文件,选择仅结构,在导出的SQL文件中就会有建表语句,一般建表语句从drop开始复制,到字符集结束复制即可
3.当发现自动递增的字段时,建议去除掉此字段,人为不干涉
drop procedure if exists demo2;
create procedure `practice`.`demo2`(in num int)
begin
declare i int;-- 声明变量
set i = 0; -- 初始化值为0
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密码',
`sex` varchar(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` datetime DEFAULT NULL COMMENT '出生日期',
`address` varchar(100) DEFAULT NULL COMMENT '家庭住址',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
-- 或者 truncate table student;。这个语句也是清除表数据使用,相比于上面,简单。
while(i<=num)do -- 循环开始
INSERT INTO `practice`.`student` (`name`, `pwd`, `sex`, `birthday`, `address`, `email`) VALUES ('宋七', i, '男', '2000-02-17 10:19:15', '水里', NULL);
set i = i+1;
end while; -- 循环结束
end;
call demo2(5);