当前位置:   article > 正文

Mysql存储过程_mysql 存储过程 declare table

mysql 存储过程 declare table

学习技术需要掌握

作用、原理、安装步骤、工具使用、模拟演示、注意细节、优点缺点

一、mysql存储过程的作用和原理 

原理:mysql存储过程是一组为了完成特定功能的sql语句集,经过编译后存储在数据库中,需要使用时,给定参数调用执行即可。

作用:简化开发人员的工作,减少数据在数据库和应用服务器之间的传输,提高数据处理的效率

二、存储过程的基本操作

① 创建一个存储过程

  1. delimiter $ ##分隔符;改成$
  2. CREATE procedure pro_test1()
  3. BEGIN
  4. SELECT 'hello mysql';
  5. END$
  6. delimiter ; ##分隔符$改成;

解析: delimiter mysql的默认执行分割符是“;”分号, 因为我们的存储过程中有代码要使用分号,如果还是以分号为结束符的话,存储过程就会报错,所以最开始需要把分隔符分号换成$符号,最后改成分号;

存储过程的创建的语法

  1. CREATE procedure pro_test1() 
  2. BEGIN
  3.     sql代码
  4. END$

② 执行存储过程

CALL pro_test1();

③ 查询存储过程

1、可以在mysql.proc表查看

SELECT * FROM mysql.proc ;

2、查看存储过程的状态

SHOW procedure status

3、查看存储创建的语句

SHOW CREATE PROCEDURE pro_test1;

④ 删除存储过程

DROP procedure pro_test1;

三、存储过程的语句

① 定义变量

declare var_name type [default value]
  1. delimiter $ ##分隔符;改成$
  2. CREATE procedure pro_test3()
  3. BEGIN
  4. declare num int DEFAULT 10; ##声明一个int变量
  5. declare str varchar(100) DEFAULT "哈哈"; ##定义一个字符串
  6. select str;
  7. SELECT num;
  8. END$
  9. delimiter ; ##分隔符$改成;

变量类型为mysql的数据类型,如int、float、date、varchar(length)

 ② 给变量赋值,修改变量

  1. delimiter $ ##分隔符;改成$
  2. CREATE procedure pro_test4()
  3. BEGIN
  4. declare num int DEFAULT 10; ##声明一个变量
  5. set num = num + 10; ##第一种 直接用set
  6. SELECT num;
  7. SELECT COUNT(*) into num FROM system_data; ##第二种 使用into
  8. SELECT num;
  9. END$
  10. delimiter ; ##分隔符$改成;

解析:有两种方式进行赋值:1、set命令 2、在sql语句中into命令

③ 条件判断语句

  1. delimiter $ ##分隔符;改成$
  2. CREATE procedure pro_test5()
  3. BEGIN
  4. declare height int default 175;
  5. declare msg varchar(50) default '';
  6. if height >= 180 then ## if 判断 then 结尾
  7. set msg = '身材高挑';
  8. elseif height >= 170 and height < 180 then ## elseif 判断 then 结尾
  9. set msg = '标准身材';
  10. else
  11. set msg = '一般身材';
  12. end if; ##end if; 结尾
  13. SELECT msg;
  14. END$
  15. delimiter ; ##分隔符$改成;

 解析:条件判断跟一般的编程语句不一样,一般的编程语句时用 if () {} 判断的,而存储过程使用的 if 判断条件 then end if; 所以要注意一下。

④ 传参

1、传入参数 输入一个人的身高,判断身材什么情况

  1. delimiter $ ##分隔符;改成$
  2. CREATE procedure pro_test6(in height int) ##在存储过程名括号这里定义 in 变量名 变量类型
  3. BEGIN
  4. ##declare height int default 175;
  5. declare msg varchar(50) default '';
  6. if height >= 180 then
  7. set msg = '身材高挑';
  8. elseif height >= 170 and height < 180 then
  9. set msg = '标准身材';
  10. else
  11. set msg = '一般身材';
  12. end if;
  13. SELECT msg;
  14. END$
  15. delimiter ; ##分隔符$改成;

调用

CALL pro_test6(170);  ##在括号里面调用

2、 输出参数

  1. delimiter $ ##分隔符;改成$
  2. CREATE procedure pro_test7(in height int, out msg varchar(100)) ##在存储过程名这里定义 in 变量名 变量类型 out为输出参数
  3. BEGIN
  4. if height >= 180 then
  5. set msg = '身材高挑';
  6. elseif height >= 170 and height < 180 then
  7. set msg = '标准身材';
  8. else
  9. set msg = '一般身材';
  10. end if;
  11. SELECT msg;
  12. END$
  13. delimiter ; ##分隔符$改成;

解析:out msg varchar(100) 为输出参数

调用:放入一个输出参数,然后在打印就可以显示,@msg表示一个用户会话变量

  1. CALL pro_test7(180, @msg);
  2. SELECT @msg;

⑤ case 条件判断

1、第一种方式, 输入一个月份,判断该月份属于第几季度

  1. delimiter $
  2. CREATE procedure pro_test8(in mon int)
  3. begin
  4. declare qua varchar(10);
  5. CASE
  6. WHEN mon >=1 AND mon <=3 THEN ##格式是 when 条件 then 代码
  7. set qua = '第一季度';
  8. WHEN mon >=4 AND mon <= 6 THEN
  9. set qua = '第二季度';
  10. WHEN mon >= 7 AND mon <= 9 THEN
  11. set qua = '第三季度';
  12. WHEN mon >= 10 AND mon <= 12 THEN
  13. set qua = '第四季度';
  14. ELSE
  15. set qua = '错误';
  16. end case; ##记得这里一定要加入分号
  17. SELECT qua;
  18. end$
  19. delimiter ;
  20. call pro_test8(12); ##调用

解析:这种方式采用的就是 when 条件判断 then 代码 else 代码的方式

2、第二种方式  类似于编程语言中的switch,case 后面放变量

输入一个参数,判断这个变量是那个支付

  1. delimiter $
  2. create procedure pro_test9(in pay_type int)
  3. BEGIN
  4. declare pay_type_msg varchar(20);
  5. case pay_type
  6. when 1 then
  7. SET pay_type_msg = '微信支付';
  8. when 2 then
  9. SET pay_type_msg = '支付宝支付';
  10. WHEN 3 then
  11. SET pay_type_msg = '银行卡支付';
  12. ELSE
  13. set pay_type_msg = '其他方式支付';
  14. end case;
  15. SELECT pay_type_msg;
  16. end$
  17. delimiter ;
  18. CALL pro_test9(100);

⑥ while 循环

从1+n 的循环语句

  1. delimiter $
  2. CREATE PROCEDURE pro_test10(in n int)
  3. BEGIN
  4. DECLARE sum int DEFAULT 0;
  5. DECLARE i int DEFAULT 0;
  6. WHILE i <= n DO ##循环的条件判断
  7. set i = i + 1;
  8. set sum = sum + i;
  9. END while; ##循环结束 一定需要分号结束
  10. SELECT sum;
  11. END$
  12. delimiter ;
  13. call pro_test10(100);

解析:while循环使用格式

while 判断条件 do

代码

end while; ##记得这里一定需要分号

⑥ repeat 循环

统计1到n相加的循环语句

  1. delimiter $
  2. CREATE PROCEDURE pro_test11(in n int)
  3. BEGIN
  4. DECLARE sum int DEFAULT 0;
  5. repeat
  6. set sum = sum + n;
  7. set n = n - 1;
  8. until n = 0 ##这里不能写分号,不然语法报错
  9. END repeat;
  10. SELECT sum;
  11. END$
  12. delimiter ;
  13. call pro_test11(100);

解析:

repeat 
        代码
        until n = 0 ##这里不能写分号,不然语法报错, 如果until满足条件则退出
END repeat;

⑦ loop循环

统计1到n相加的循环语句

  1. delimiter $
  2. CREATE PROCEDURE pro_test12(in n int)
  3. BEGIN
  4. DECLARE sum int DEFAULT 0;
  5. c:LOOP ##申明一个loop循环 c表示循环的名称,后面停止和结束需要使用
  6. set sum = sum + n;
  7. set n = n - 1;
  8. if n <= 0 then
  9. leave c; ##停止 循环
  10. end if;
  11. END LOOP c; ##结束循环 c是前面定义的
  12. SELECT sum;
  13. END$
  14. delimiter ;
  15. call pro_test12(10);

解析: loop需要使用 leave来停止

c : loop ##需要定义循环的标签,方便后面使用

四、游标

① 一个游标的代码 

测试表

  1. create table user (
  2. id int auto_increment,
  3. name varchar(100),
  4. age int,
  5. primary key(id)
  6. ) ENGINE = INNODB

使用游标读取数据 

  1. delimiter $
  2. CREATE PROCEDURE pro_test12()
  3. BEGIN
  4. declare id int(11);
  5. declare name VARCHAR(100) CHARACTER SET utf8mb4;
  6. declare age int(11);
  7. declare has_data tinyint default 1;
  8. declare user_result cursor for select * from user; ##定义游标变量 user_result; 必须申请在处理程序之前
  9. ### 捕获系统抛出的 not found 错误,如果捕获到,将 has_data 设置为 0 相当于try异常
  10. declare continue handler for not found set has_data = 0; ## 检测游标是否循环完,必须放到定义游标的下面
  11. ##打开游标
  12. OPEN user_result;
  13. ##循环游标
  14. WHILE has_data = 1 DO
  15. fetch user_result into id, name, age; ##循环获取每行数据,注意这里的id,name,age的变量类型必须是跟表定义的类型一致
  16. select CONCAT('id=', id, 'name=', name, 'age=', age);
  17. END WHILE;
  18. ##关闭游标
  19. CLOSE user_result;
  20. END$
  21. delimiter ;

 解析:读取游标必须要

①定义游标变量,且定义游标是否结束变量

②开启

③循环读取数据

④关闭游标

② 多个游标的代码 

  1. delimiter $
  2. CREATE PROCEDURE pro_test12()
  3. BEGIN
  4. declare id int(11);
  5. declare name VARCHAR(100) CHARACTER SET utf8mb4;
  6. declare nam2 mediumtext CHARACTER SET utf8mb4;
  7. declare age int(11);
  8. declare has_data tinyint default 1;
  9. declare has_data2 tinyint default 1;
  10. declare user_result cursor for select * from user; ##定义游标变量 user_result; 必须申请在处理程序之前
  11. declare test_result cursor for select * from test05;
  12. ### 捕获系统抛出的 not found 错误,如果捕获到,将 has_data 设置为 0 相当于try异常
  13. ## 这里需要注意continue handler和exit handler 的区别,开始我使用的的exit handler直接监控到游标没有了 程序执行停止运行了,查了半天不知道什么问题
  14. declare continue handler for not found set has_data = 0, has_data2 = 0;
  15. ##打开游标
  16. OPEN user_result;
  17. ##循环游标
  18. while has_data = 1 DO
  19. fetch user_result into id, name, age; ##循环获取每行数据,注意这里的id,name,age的变量类型必须是跟表定义的类型一致
  20. select CONCAT('id=', id, 'name=', name, 'age=', age);
  21. END while;
  22. ##关闭游标
  23. CLOSE user_result;
  24. set has_data2 = 1; ##上面的循环把has_data设置=0,所以这里需要重新设置=1
  25. ##打开游标
  26. OPEN test_result;
  27. ##循环游标
  28. WHILE has_data2 = 1 DO
  29. fetch test_result into id, nam2; ##循环获取每行数据,注意这里的id,name,age的变量类型必须是跟表定义的类型一致
  30. select CONCAT('id=', id, 'name=', nam2);
  31. END WHILE;
  32. ##关闭游标
  33. CLOSE test_result;
  34. END$
  35. delimiter ;

注意细节:

定义游标没有后参数改变的变量,不能使用 declare exit handler,要使用continue handler。

declare continue handler for not found set has_data = 0, has_data2 = 0;

五、函数

定义一个函数,传userId,返回userId的行数;

跟存储过程不同的时,可以使用return变量 

  1. delimiter $
  2. create function fun1(userId int) returns int ##函数定义 返回int,记得这里是returns
  3. BEGIN
  4. DECLARE cnum int;
  5. select COUNT(*) INTO cnum from test04 where user_id = userId;
  6. return cnum; ##返回变量
  7. end$
  8. delimiter ;

调用使用select fun1(1); 

SELECT fun1(1);

六、一些存储过程的案例

①  批量导入100万的随机测试数据 

  1. delimiter $
  2. CREATE procedure test_pro(in n int(11))
  3. BEGIN
  4. declare temp_char char(1);
  5. ###select repeat(temp_char, floor(1 + rand() * (100 - 1)));
  6. WHILE n > 0 DO
  7. ##随机取出一个字符
  8. SET temp_char = char(floor(33 + rand() * (93 - 1)));
  9. insert into user value(null, repeat(temp_char, floor(1 + rand() * (100 - 1))), 11);
  10. SET n = n - 1;
  11. END WHILE;
  12. end$
  13. delimiter;

 char ASCII的数字转换成字符串

 repeat 是将字符串重复多少个

七、存储过程和函数的区别

1、 函数可以使用return返回值的形式,而存储过程只能只用 out 的参数形式,

2、函数调用直接用select, 存储过程需要使用 call命令

3、其他的好像没有什么区别,中间的代码都是可以共用的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/889957
推荐阅读
相关标签
  

闽ICP备14008679号