大纲:

  1. 创建、删除、调用。
  2. 声明变量、变量赋值、存储过程的入参
  3. 声明游标
  4. 声明异常处理器
  5. 判断
  6. 循环
  7. 使用心得
  8. mybatis调用存储过程

一、创建、删除、调用

  • 创建

    DELIMITER $$ #修改分隔符
    CREATE PROCEDURE test(IN pname VARCHAR(50)) #括号里是入参。
    BEGIN
    select pname; #存储过程中的语句用;结尾
    END$$ #存储过程本身用修改后的分隔符$$结尾
    DELIMITER ; ##还原分隔符

    begin、end之间是存储的执行的代码块。

   tips:mysql不支持匿名块(没有create procedure,直接写begin、end之间的内容),因此msql的代码块只能放在存储过程,自定义函数,触发器中。

  • 删除

    DROP PROCEDURE IF EXISTS test; #存储过程

    和表一样建立前确保数据库中没有同名存储过程。

  • 调用
    CALL test('xx');

    调用用call命令、这里参数传一个字符串进去、调用后显示xx。

二、声明变量、变量赋值、存储过程的入参

  • declare声明变量
  • set是直接赋值(可以用 '=' 号赋值,也可以用 ':=' 赋值,本文例子中都是用 '=' 赋值的。但之后的学习中发现用这种 ':=' 方式赋值更规范一些。)
  • select是将查询的结果进行赋值
    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test(IN pname VARCHAR(50))
    BEGIN
    DECLARE prefix VARCHAR(20); #声明变量
    set prefix = 'nihao:'; #select 'nihenhao:' into prefix; 赋值
    select concat(prefix,pname); #concat函数:拼接2个字符串
    END$$
    DELIMITER ;
    CALL test('xx');:赋值方式有2种、根据需求选择。
  • 创建存储过程的时候已经提到了,存储过程可以有入参IN,也可以有出参OUT,还可以有出入参INOUT。IN类型只能作为传入参数使用,OUT只能作为传出参数使用,只有INOUT既可以传入存储过程又能传出来。
    drop PROCEDURE test;
    DELIMITER $$
    CREATE PROCEDURE test( IN people VARCHAR(8), OUT name VARCHAR(8),INOUT age INT )
    BEGIN
    IF people = 'man'
    THEN SET name := 'xiaoming';
    SET age :=age+1;
    ELSE SET name := 'xiaohong';
    SET age :=age+10;
    END IF;
    END $$ set @people = 'man'; #@var_name这样的写法是声明一个用户变量,只有在本次连接的客户端中有效。这里声明了3个变量people、name、age
    set @name = null;
    set @age = 6;
    call test(@people,@name,@age);
    SELECT @people,@name,@age from dual; #结果:man xiaoming 7

三、声明游标

  • 准备一个测试表

    TRUNCATE names;
    create table names
    (
    name VARCHAR(20),
    age int
    );
    INSERT into names VALUES ('lby',45);
    INSERT into names VALUES ('lala',23);
  • 游标可以理解为是一个带指针的结果集。
    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test()
    BEGIN
    DECLARE name VARCHAR(20);
    DECLARE age int;
    DECLARE temp VARCHAR(50);
    DECLARE c1 CURSOR FOR select * from names; #声明游标
    OPEN c1; #使用游标前打开游标
    FETCH c1 INTO name,age; #将游标中的第一行依次付给name,age(name=lby,age=45)。tips:游标列数和变量数要相同。
    set temp = CONCAT(name,age);
    FETCH c1 INTO name,age; #第一次fetch后指针下移动,赋值第二行给name,age(name=lala,age=23)。
    CLOSE c1; #使用游标后关闭游标
    set temp = CONCAT(temp,CONCAT(name,age));
    SELECT temp from dual; #lby45lala23
    END$$
    DELIMITER ;
    CALL test();

四、声明异常处理器

  • 当sql执行时报错时会报出相应的sqlstate,根据不同的sqlstate我们可以给出不同的处理。--附一个sqlstate的详解:blog.csdn.net/u014653854/article/details/78986780
  • 处理器有2种:exit、continue。
    TRUNCATE names; #清空names表使fetch报错SQLSTATE''
    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test()
    BEGIN
    declare age int default 0 ;
    declare name VARCHAR(20) default 0 ;
    declare flag int default 0;
    DECLARE c1 CURSOR FOR select * from names;
    declare CONTINUE HANDLER FOR SQLSTATE '' SET flag = 111; # continue handler 检测报错为02000的时候 将flag设为111,存储过程继续执行,如果换为exit handler在行为完处理语句set flag=111后直接退出存储过程。
    OPEN c1;
    FETCH c1 into name,age; #当执行这句时会报错sqlstate:02000 ,continue handler触发set flag= 111,继续执行后面的代码。
    CLOSE c1;
    select flag; #111
    END$$
    DELIMITER ;
    CALL ifpay_ccpay.test();

五、判断

  • if判断

    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test(in age int)
    BEGIN
    declare flag VARCHAR(20);
    IF age = 1 THEN SET flag = '一';
    ELSEIF age = 2 THEN SET flag = '二';
    ELSE SET flag = 'I DONT KNOW';
    END IF; #结束标志
    select flag; #二
    END$$
    DELIMITER ;
    CALL ifpay_ccpay.test(2);

六、循环

循环有三种

  • while循环

    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test()
    BEGIN
    DECLARE age int DEFAULT 0;
    mywhile:
    WHILE age < 5 #条件,
    DO
    set age = age+1; #do与endwhile之间是循环内容
    END WHILE ;
    SELECT age; #5
    END$$
    DELIMITER ;
    CALL test();
  • repeat循环
    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test()
    BEGIN
    DECLARE age int DEFAULT 0;
    mywhile:
    repeat
    set age = age+1; #循环体
    UNTIL age>3 END REPEAT ; #条件
    SELECT age; #4
    END$$
    DELIMITER ;
    CALL test();
  • loop循环
    DROP PROCEDURE IF EXISTS test;
    DELIMITER $$
    CREATE PROCEDURE test()
    myproc: #存储过程的label
    BEGIN
    DECLARE age int DEFAULT 0;
    DECLARE count int DEFAULT 10;
    myloop: #loop的label
    LOOP
    set age = age +1;
    IF age < 5 then
    ITERATE myloop; #忽略后面代码继续执行。(continue)
    END IF;
    set count = count - 1;
    SELECT 'haha';
    LEAVE myloop; #离开循环。(break) leave也可直接用于存储过程本身myproc,如果这里换成myproc,则显示haha
    END LOOP;
    SELECT age,count; #5 9
    END$$
    DELIMITER ;
    CALL test();

   代码中有3个概念:label、iterate、leave

   label:名称标签,while、repeat、loop循环或者 存储过程本身begin关键字前面都可以加一个名称标签。  

   iterate:用于循环、继续当前循环,相当于java循环中的continue。

   leave:1.用于循环、离开当前循环,相当于java循环中的break。

        2.也可用于存过过程本身,直接离开存过过程。

循环小结:1.while repeat区别在于:while 先判断循环条件再循环,repeat 线循环后判断。

     2.loop没有结束条件,需要手动退出。

     3.iterate、leave也可以用于while、repeat。

七、使用心得

  1. 存储过程中慎用delete语句。
  2. 存储过程适合一些有规律的数据操作,比如根据一些业务规则初始化一些数据。
  3. 尽量不要用它代替简单的业务sql,因为存储过程的维护、迁移、易读性都不如直接写在代码中好。

八、mybatis调用存储过程

调用方式参考我另一篇文章:mybatis调用存储过程

mysql 存储过程(代码块)的更多相关文章

  1. 写一个MySql存储过程实现房贷等额本息还款计算(另外附javascript代码)

    写一个MySql存储过程实现房贷等额本息还款计算 MySql存储过程代码如下: DROP procedure IF EXISTS `calc_equal_interest_proc`; DELIMIT ...

  2. Mysql基础代码(不断完善中)

    Mysql基础代码,不断完善中~ /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限 ...

  3. mysql存储过程和存储函数

    mysql存储过程和存储函数 存数函数代码示例: DROP PROCEDURE IF EXISTS calc_ci_day_suc_rate; delimiter // CREATE FUNCTION ...

  4. MYSQL存储过程、游标、触发器

    MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成  存储过程简单来说,就是为以后的使用而保存的一 ...

  5. Mysql存储过程调用

    mysql存储过程实例教程 发布时间:2014-04-09编辑:JB01 这篇文章主要介绍了mysql存储过程的使用方法,mysql存储过程实例教程,有需要的朋友参考下.   1.1create  p ...

  6. mysql存储过程之异常处理篇

    mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现 语法如下: DECLARE handler_type HANDLER FOR condition_value[, ...

  7. 《MySQL 存储过程编程》-读书笔记

    本书结构: 第一部分:存储编程基础 第1章:存储过程程序基础 第2章:MySQL存储编程指南 第3章:语言基础 第4章:语句块 第5章:在存储程序中使用SQL 第一章:MySQL存储程序介绍 存储程序 ...

  8. MySQL存储过程(一)

    1.1 CREATE  PROCEDURE (创建) CREATE PROCEDURE存储过程名 (参数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的参数列必须总是存在.如果没有参 ...

  9. MySQL存储过程(转载)

    转自:http://www.blogjava.net/sxyx2008/archive/2009/11/24/303497.html 1.1         CREATE  PROCEDURE  (创 ...

随机推荐

  1. QT中显示图像数据

    博客转载自:https://blog.csdn.net/lg1259156776/article/details/52325091 一般图像数据都是以RGBRGBRGB……字节流的方式(解码完成后的原 ...

  2. latex公式怎么变成图片格式

    由于这几天正在复习高中的数学,想写一些博客记录一下,发现数学公式的输入是一个问题,后来知道了latex,去youtube学习了一点入门教程发现挺简单的,不过有一个问题,latex生成的是pdf格式啊, ...

  3. Mac OS X 安装教程

    1)10.8.3 http://bbs.pcbeta.com/viewthread-1317754-1-1.html 2)10.9 http://blog.csdn.net/kissing_huo/a ...

  4. post请求时,出现relationship name error

    原因:在post请求,其属性名在代码中已经修改为partyLocationDtos,但是在swagger中,仍然为partyLocations. 因此,报错.记住,在post请求的时候,要一一对应.写 ...

  5. JavaWeb_反射

    一个类有多个组成部分,例如:成员变量,方法,构造方法等.反射就是加载类,并解剖出类的各个组成部分. 编程时什么情况下才需要加载类,并解剖出累的各个组成部分呢? 反射是用来做框架的. 从配置文件中解读类 ...

  6. 《Effective Java》第9章 异常

    第58条:对可恢复的情况使用受检异常,对编程错误使用运行时异常 Java程序设计语言提供了三种可抛出结构(throwable) ;受检的异常(checked exception)运行时异常(run-t ...

  7. sizeof的用法与字节对齐

    一.sizeof是什么? sizeof是一种预编译处理,不是函数,不是一元表达式.也即,作用阶段在编译期. 二.功能是什么? sizeof返回变量或类型的字节数. 三.调用方式 sizeof(obje ...

  8. 【C#】ORM框架

    ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁. Java典型的ORM框架有个:Hibernate,my ...

  9. Gazebo学习随记5 杂记

    模拟建筑编辑器 将卫星图导入世界,方便空中机器人模拟 录像和回放 记录筛选 给关节添加力/扭矩  一开始不知道哪里出现了偏差以一动不动,重启就好了 HDF5数据集 代码内省 模型插件   !!!我终于 ...

  10. (原创)团体程序设计天梯赛-练习集 L1-048 矩阵A乘以B (15 分)

    给定两个矩阵A和B,要求你计算它们的乘积矩阵AB.需要注意的是,只有规模匹配的矩阵才可以相乘.即若A有R​a​​行.C​a​​列,B有R​b​​行.C​b​​列,则只有C​a​​与R​b​​相等时,两 ...