例子

-- 秒杀执行存储过程
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.储存过程参数

  • 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>

从一个例子入门Mysql储存过程的更多相关文章

  1. mysql储存过程入门学习

    转载至:https://www.yiibai.com/mysql/getting-started-with-mysql-stored-procedures.html 1.mysql储存过程的创建 DE ...

  2. MySQL 储存过程-原理、语法、函数详细说明

    Mysql储存过程是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之就是一组已经写好的命 ...

  3. Mysql 储存过程以及 python callproc调用

    一.存储过程(stored procedure) 存储过程将存入的一系列SQL语句进行预编译,执行并存放在数据库中,之后如果需要使用sql语句对这一组sql进行访问时可以直接提取(很好理解 存储过程就 ...

  4. MySQL储存过程

    储存过程 本文章原创,转载需注明出处. 前提: 在大型数据库中 来源: 为了完成特定功能的SQL语句集 定义: 储存在数据库中, 用户通过指定储存过程的名字并给出参数(带有参数的)来执行它 声明: 储 ...

  5. MySQL储存过程详解

    我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的 ...

  6. mysql 储存过程

    存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. --------------------基本语法-------------------- 一.创建存储过程cr ...

  7. Mysql储存过程7: case

    #用在储存过程中: create procedure k() begin declare number int; )); case number then select '>0'; else s ...

  8. Mysql储存过程4:mysql变量设置

    默认全局变量是两个@@开头, 可用show variables查看所有默认变量: @@user #declare定义变量只能用在储存过程中 #declare 变量名 数据类型 可选类型 declare ...

  9. Mysql储存过程2:变量定义与参数传递

    #储存过程 中的变量定义 declare 变量名 类型 可选类型 -- 跟建表差不多 create procedure p() begin ); ; select age+number; end$ / ...

随机推荐

  1. html:常见行内标签,常见块级标签,常见自闭合标签

    本文内容: 常见行内标签 常见块级标签 常见自闭合标签 首发日期:2018-02-12 修改: 2018-04-25:删除了不常用的标签 常见行内标签: 什么是行内标签: 行内标签就是在页面内只占据刚 ...

  2. SQL SERVER 查询表的各字段长度

    SELECT a.name,b.name,c.DATA_TYPE,b.max_length FROM sys.tables a join sys.columns b on b.object_id = ...

  3. SQL WHERE 子句

    WHERE 子句 如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句. 语法 SELECT 列名称 FROM 表名称 WHERE 列 运算符 值 释意:选取 [列] 来自 [ ...

  4. ALTER添加列后,立即UPDATE该列会报错

    SQL 2008 R2 请看语句: ALTER TABLE #t ADD col2 INT UPDATE #t SET col2 = 0 报错:列名'col2'无效. 但如果紧接的是SELECT,一切 ...

  5. VMWare 虚拟机设置网络访问

    使用桥接模式 将本机IP设置为和虚拟机IP在同一个可以上网的网段中

  6. 利用开机账户登录“轻松访问”创建Windows后门

    利用开机账户登录“轻松访问”创建Windows后门 实验原理: 利用登录账户界面的“轻松访问”中的“放大镜”,把它替换为cmd.exe程序,实现在不登录的情况下打开命令提示符,并进行一些操作(打开的c ...

  7. February 21st, 2018 Week 8th Wednesday

    Our life is what our thoughts make it. 我们的思想成就了我们的生活. The mind is everything. What you think, you be ...

  8. 深入理解Ribbon之源码解析

    什么是Ribbon Ribbon是Netflix公司开源的一个负载均衡的项目,它属于上述的第二种,是一个客户端负载均衡器,运行在客户端上.它是一个经过了云端测试的IPC库,可以很好地控制HTTP和TC ...

  9. 再谈:为什么开源C/C++开源框架极昂贵?

        今天读了一篇文章:<腾讯前员工创业笔记:那些跟钱有关的事儿>(http://tech.163.com/14/0515/08/9S9975C5000915BF.html),摘录两段: ...

  10. 给定一个正整数n,返回从1到n构成的所有的BST

    public class C3 { public static void main(String[] args) { ArrayList<TreeNode> res = generateT ...