zoukankan      html  css  js  c++  java
  • 从一个例子入门Mysql储存过程

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

    例子

    -- 秒杀执行存储过程
    DELIMITER $$ -- 将分隔符; 转换为 $$
    -- 定义存储过程
    -- 参数: in 输入参数; out 输出参数
    -- row_count():返回上一条修改类型sql(delete,insert,update)的影响行数
    -- row_count: 0:未修改数据; >0:表示修改的行数; <0:sql错误/未执行修改sql
    CREATE PROCEDURE `seckill`.`execute_seckill`
      (in v_seckill_id bigint,in v_phone bigint,
        in v_kill_time timestamp,out r_result int)--创建储存过程
      BEGIN-- 开始执行
        DECLARE insert_count int DEFAULT 0;-- 定义变量
        START TRANSACTION;--开启事物管理
        insert ignore into success_killed
          (seckill_id,user_phone,create_time)
          values (v_seckill_id,v_phone,v_kill_time);--执行insert语句
        select row_count() into insert_count;--返回影响行数
        IF (insert_count = 0) THEN
          ROLLBACK;--事务回滚
          set r_result = -1;--返回未修改数据
        ELSEIF(insert_count < 0) THEN
          ROLLBACK;--事务回滚
          set R_RESULT = -2;--返回未知错误
        ELSE
          update seckill
          set number = number-1
          where seckill_id = v_seckill_id
            and end_time > v_kill_time
            and start_time < v_kill_time
            and number > 0;--执行update语句
          select row_count() into insert_count;--返回影响行数
          IF (insert_count = 0) THEN
            ROLLBACK;--事务回滚
            set r_result = 0;--返回未修改数据
          ELSEIF (insert_count < 0) THEN
            ROLLBACK;--事务回滚
            set r_result = -2;--返回未知错误
          ELSE
            COMMIT;--提交,事务结束
            set r_result = 1;--返回执行成功
          END IF;--结束IF语句
        END IF;--结束IF语句
      END;--结束储存过程
    $$--结束sql
    -- 存储过程定义结束
    
    DELIMITER ;--还原分隔符为;
    --
    set @r_result=-3;--定义用户变量
    -- 执行存储过程
    call execute_seckill(1003,13502178891,now(),@r_result);
    -- 获取结果
    select @r_result;
    
    -- 存储过程
    -- 1:存储过程优化:事务行级锁持有的时间
    -- 2:不要过度依赖存储过程
    -- 3:简单的逻辑可以应用存储过程
    -- 4:QPS:一个秒杀单6000/qps
    

    1.储存过程参数

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

    • IN:参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
    • OUT:该值可在存储过程内部被改变,并可返回
    • INOUT:调用时指定,并且可被改变和返回

    • [IN|OUT|INOUT] 参数名 数据类型
    • 比如: IN number INT
    • 例子:
    DELIMITER //
      CREATE PROCEDURE myproc(OUT s int)
        BEGIN
          SELECT COUNT(*) INTO s FROM students;
        END
        //
    DELIMITER ;
    

    2.Mybatis调用储存过程

    <!-- statementType 声明指向的是什么类型,其中CALLABLE是执行存储过程和函数的-->
    <select id="killByProcedure" parameterType="map" statementType="CALLABLE">
        call execute_seckill(
            #{seckillId,jdbcType=BIGINT,mode=IN},
            #{phone,jdbcType=BIGINT,mode=IN},
            #{killTime,jdbcType=TIMESTAMP,mode=IN},
            #{result,jdbcType=INTEGER,mode=OUT}
        )
    </select>
    

    版权声明

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

  • 相关阅读:
    AngularJs 键盘事件和鼠标事件
    Linux的net.ipv4.tcp_timestamps参数
    实战:tcp链接rst场景tcpdump分析
    C++ map使用总结
    C++ 11常见功能介绍:auto,decltype,nullptr,for,lambda
    BLOCK层基本概念:bio,request,request_queue
    C: 字符数组中的空去掉
    代码静态分析工具-splint的学习与使用[转]
    代码分析工具splint安装介绍
    gcc/g++ 如何支持c11/c++11标准编译
  • 原文地址:https://www.cnblogs.com/onblog/p/13035626.html
Copyright © 2011-2022 走看看