mysql 存储过程(代码块)
大纲:
- 创建、删除、调用。
- 声明变量、变量赋值、存储过程的入参
- 声明游标
- 声明异常处理器
- 判断
- 循环
- 使用心得
- 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。
七、使用心得
- 存储过程中慎用delete语句。
- 存储过程适合一些有规律的数据操作,比如根据一些业务规则初始化一些数据。
- 尽量不要用它代替简单的业务sql,因为存储过程的维护、迁移、易读性都不如直接写在代码中好。
八、mybatis调用存储过程
调用方式参考我另一篇文章:mybatis调用存储过程
mysql 存储过程(代码块)的更多相关文章
- 写一个MySql存储过程实现房贷等额本息还款计算(另外附javascript代码)
写一个MySql存储过程实现房贷等额本息还款计算 MySql存储过程代码如下: DROP procedure IF EXISTS `calc_equal_interest_proc`; DELIMIT ...
- Mysql基础代码(不断完善中)
Mysql基础代码,不断完善中~ /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限 ...
- mysql存储过程和存储函数
mysql存储过程和存储函数 存数函数代码示例: DROP PROCEDURE IF EXISTS calc_ci_day_suc_rate; delimiter // CREATE FUNCTION ...
- MYSQL存储过程、游标、触发器
MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成 存储过程简单来说,就是为以后的使用而保存的一 ...
- Mysql存储过程调用
mysql存储过程实例教程 发布时间:2014-04-09编辑:JB01 这篇文章主要介绍了mysql存储过程的使用方法,mysql存储过程实例教程,有需要的朋友参考下. 1.1create p ...
- mysql存储过程之异常处理篇
mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现 语法如下: DECLARE handler_type HANDLER FOR condition_value[, ...
- 《MySQL 存储过程编程》-读书笔记
本书结构: 第一部分:存储编程基础 第1章:存储过程程序基础 第2章:MySQL存储编程指南 第3章:语言基础 第4章:语句块 第5章:在存储程序中使用SQL 第一章:MySQL存储程序介绍 存储程序 ...
- MySQL存储过程(一)
1.1 CREATE PROCEDURE (创建) CREATE PROCEDURE存储过程名 (参数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的参数列必须总是存在.如果没有参 ...
- MySQL存储过程(转载)
转自:http://www.blogjava.net/sxyx2008/archive/2009/11/24/303497.html 1.1 CREATE PROCEDURE (创 ...
随机推荐
- Blender 工具使用——模式切换
Blender 工具使用--模式切换 制作骨架时 在物件模式(Object Mode)下使用鼠标右键选中一个骨架,按Tab键,可以切换为编辑模式(Edit Mode),按Ctrl + Tab可以进入骨 ...
- AbstractFactoryPattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...
- Ryouko's Memory Note
题目意思:一个书有 n 页,每页的编号依次从 1 到 n 编排.如果从页 x 翻到页 y,那么|x-y|页都需要翻到(联系生活实际就很容易理解的了).接着有m pieces 的 information ...
- WordCount编码与测试
1. github项目地址:https://github.com/wwwwu/WordCount 2.PSP表格: PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning ...
- Oracle数据库之多表查询一
上一篇给大家介绍了数据的单表查询,相信大家对于单表的查询应该都有了一些了解.单表查询在数据库中的使用会有一些,但并不是很多,但是作为初学者,我们需要学习单表查询的思路.今天呢,我们为大家介绍一下数据库 ...
- AttributeError: 'module' object has no attribute 'gfile'
While running TensorFlow's classify_image, getting AttributeError: 'module' object has no attribute ...
- 二维码的生成细节和原理 -- 转http://news.cnblogs.com/n/191671/
二维码又称 QR Code,QR 全称 Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的 Bar Code 条形码能存更多的信息,也能表示更多的数据类型:比如:字 ...
- sqlserver小批量导数据
USE [KM_Voice] GO /****** Object: StoredProcedure [dbo].[proc_insert] Script Date: 01/09/2015 18: ...
- Mybatis环境搭建中的案例分析 及 如果自己编写DAO接口的实现类
Mybatis环境搭建中的案例分析public static void main (String[] args) throws Exception { //读配置文件 //第一个: 使用类加载器,只能 ...
- Mysql union
union简单来说就是多表链接,主要是用于(模糊)查询,全库搜索 多表搜索需要先将需要查询的表用union连接,然后在每一个union后面添加上相同的where条件 菜鸟教程