游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的.

动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此, 感谢他一下, 建华锅锅.

事务在前面的篇章中其实已经出现过了, 这个东西好像还是程序中用的比较多一点.

由于之前的工作中碰到过一个场景, 正好将游标,动态sql,事务都用上了, 那么我也弄一个例子好了, 想了一个别的场景, 与工作的那个场景不相干, 并没有泄露公司业务机密之类的啊.

先看例子吧, 然后在后面, 我补上语法.

一、例子

1. 建表

  既然是讲例子, 当然不能忘记建表嘛, 从0开始.

create table Goods
(
Id int not null PRIMARY key auto_increment,
Code varchar() comment '编码',
Name varchar() comment '名称',
Count int comment '数量',
Brand varchar() comment '品牌'
) default charset=utf8 comment '商品表'; create table GoodDetails
(
Id int not null PRIMARY key auto_increment,
GId int not null comment 'Goods表Id',
   Name varchar() comment '名称',
Code varchar() comment '编码明细',
Remark varchar() comment '备注'
) default charset=utf8 comment '商品明细';

2. 加入基础数据

3. 虚拟场景介绍

公司最近进了一批物品, 就是上面的Goods表了, 并且准备给每一个物品进行编码(编码规则就是用Goods表的Code加上流水号, 去生成), 并打上条形码.

这里的功能就是生成商品明细和流水号的问题了, 一键生成. 这里通常的实现方式有两种:

方式一 : 程序生成

  在程序中, 读取需要生成的数据, 比如上面这四条, 然后循环每一条, 给数据加上编码, 总共生成出12条数据, 在吧这12条数据, 存入明细表中. 在数据量少的时候还好, 完全可以接受, 但是如果数据量多了, 那速度, 慢的让人有砸电脑的冲动. Goods表的几条数据, 到GoodDetails表中, 会变成数百, 甚至上千, 上万.

方式二 : 数据库生成

  如果不想读取出来再插入, 并且逻辑处理并不多,不复杂的情况下, 可以使用数据库去生成. 还是很方便的, 速度也提升非常多.

那这里, 我只介绍方式二了, 方式一, 只是处理麻烦一点.

4. 脚本:

delimiter $
drop PROCEDURE if EXISTS p_autocreate;
CREATE PROCEDURE `p_autocreate`(IN g_ids VARCHAR(1000), IN nolength INT)
BEGIN
DECLARE res_code INT; DECLARE res_msg VARCHAR (50); /*临时表的条数*/
DECLARE t_count INT; /**游标内使用变量**begin**/
DECLARE g_id INT; DECLARE g_code VARCHAR (50); DECLARE d_code VARCHAR (50); DECLARE g_count INT (11); DECLARE g_name VARCHAR (20);
/**游标内使用变量**end**/ /**游标的位置**/
DECLARE v_index INT DEFAULT 1; DECLARE done BIT DEFAULT 0; /*声明游标*/
DECLARE g_cursor CURSOR FOR SELECT id, CODE, NAME, COUNT FROM temp_goods; /*游标查询时, 如果找不到下一个了, 会将done置为1*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; /**创建临时表**begin**/
DROP TABLE IF EXISTS temp_goods;
CREATE TEMPORARY TABLE temp_goods (
Id INT NOT NULL, -- PRIMARY key auto_increment,
CODE VARCHAR (50),
NAME VARCHAR (20),
COUNT INT
) DEFAULT CHARSET = utf8;
/**创建临时表**end**/ /**初始化返回值**begin**/
SET res_code := "-99"; SET res_msg := "OK";
/**初始化返回值**end**/ IF (g_ids IS NOT NULL OR LENGTH(g_ids) > 0) THEN
SET @v_sql := CONCAT("INSERT INTO temp_goods(Id,Code,Name,Count) ",
" select Id,Code,Name,Count from Goods ",
" where ",
" find_in_set(id, ",
CHAR(34),
g_ids,
CHAR(34),
")>0 ;"); /*预编译此动态sql, 并存入stmt中*/
PREPARE stmt FROM @v_sql; /*执行此动态sql, 此动态sql的作用, 是从Goods中提取有效数据*/
EXECUTE stmt; /*释放此资源*/
DEALLOCATE PREPARE stmt; SELECT COUNT(1) INTO t_count FROM temp_goods; START TRANSACTION; -- 开始事务 IF (t_count > 0) THEN
/*打开游标*/
OPEN g_cursor; REPEAT
/*这里的顺序要与之前的顺序保持一致*/
FETCH g_cursor INTO g_id, g_code, g_name, g_count; IF NOT done THEN SET v_index := 1; IF (IFNULL(g_count, 0) > 0) THEN WHILE (v_index <= g_count)
DO
SET d_code := CONCAT(g_code, LPAD(v_index, nolength, "0")); INSERT INTO GoodDetails(GId, NAME, CODE) VALUES (g_id, g_name, d_code); SET v_index := v_index + 1;
END WHILE;
END IF;
END IF;
UNTIL done END REPEAT; -- 结束repeat循环
CLOSE g_cursor; /*关闭游标*/ COMMIT; -- 提交事务 ELSE ROLLBACK; -- 回滚事务 SET res_code := "10"; SET res_msg := "系统中不存在相关记录.";
END IF;
ELSE
SET res_code := "5"; SET res_msg := "请选择要生成的记录";
END IF; DROP TABLE IF EXISTS temp_goods; SELECT res_msg;
END $
delimiter ;

5. 结果:

执行这个存储过程

call p_autocreate('1,2,3,4', 3);

ok, 执行成功, 接下来, 来看一下GoodDetails表的数据:

我这里的例子, 已经是最简单的一个例子了, 在实际使用过程中, 可能比这个还要复杂一些, 数据更多一些.

不过说到这个数据量, 我倒不介意, 多做一个实验.

6. 实验

  我将各自的数据量, 都修改为 10000, 如下图, 这个时候, 要生成 40000 条数据, 并且插入到表中去. 如果使用程序处理插入数据库的方式, 确实会慢一些.

  

数据库的方式, 确实会快很多. 如下图, 生成4w条数据, 然后插入GoodDetails表中, 花了不到4s的时间. 算是一个比较快的时间了.

  

OK, 接下来, 就来介绍一下他们的语法.

二、游标

1. 语法

1.1 声明游标

  declare 游标名 cursor for select 列名 from 表

1.2 打开游标

  open 游标名

1.3 游标前进

  fetch 游标名 into 变量a, 变量b ...

1.4 关闭游标

  close 游标名

2. 注

  既然游标执行的方式, 像是一个循环, 那么什么时候才知道这个循环要结束呢.

  例子里面, 有一句话,  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 这句话的意思, 其实就是当游标找不到下一条数据的时候, 就回将变量 done 修改为1.

三、动态sql

1. 语法

1.1 准备sql变量

  此sql变量必须是字符串格式的哦. 这样可以动态生成需要执行的sql.

1.2 预编译

  PREPARE stmt FROM @v_sql;

  这里的stmt是一个变量, 名称自己取

1.3 执行

  EXECUTE stmt;

1.4 释放资源

  DEALLOCATE PREPARE stmt;

四、事务

1. 语法

到这里, 我突然不知道说些什么了. 那就简单介绍下吧

1.1 开始事务

  start transation;

1.2 提交事务

  commit;

1.3 回滚事务

  rollback;

Mysql - 游标/动态sql/事务的更多相关文章

  1. MySQL存储过程动态SQL语句的生成

    用Mysql存储过程来完成动态SQL语句,使用存储过程有很好的执行效率: 现在有要求如下:根据输入的年份.国家.节假日类型查询一个节假日,我们可以使用一般的SQL语句嵌入到Java代码中,但是执行效率 ...

  2. mysql 存储过程 动态sql例子

    proc:BEGIN ; ; ; ) DEFAULT ''; ) DEFAULT ''; ) DEFAULT '';#插入日志的表,一个活动一张表 #将局部变量转换成会话变量 #动态sql语言只接受会 ...

  3. MySQL基础----动态SQL语句

    尊重原创:http://blog.csdn.net/abc19900828/article/details/39501643   动态sql语句基本语法 1 :普通SQL语句可以用Exec执行 eg: ...

  4. mysql游标的用法及作用

    1当前有三张表A.B.C其中A和B是一对多关系,B和C是一对多关系,现在需要将B中A表的主键存到C中:常规思路就是将B中查询出来然后通过一个update语句来更新C表就可以了,但是B表中有2000多条 ...

  5. MyBatis 的动态 SQL 使用说明

    动态SQL简介 参考文档地址:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 ...

  6. MySQL通过视图(或临时表)实现动态SQL(游标)

    >参考de优秀文章 写MySQL存储过程实现动态执行SQL Dynamic cursor in stored procedure MySQL通过视图(或临时表)实现动态SQL(游标). 因在实现 ...

  7. 使用动态SQL处理table_name作为输入参数的存储过程(MySQL)

    关于mysql如何创建和使用存储过程,参考笔记<MySQL存储过程和函数创建>以及官网:https://dev.mysql.com/doc/refman/5.7/en/create-pro ...

  8. MyBatis基础_连接池与事务、动态SQL、注解开发

    一.MyBatis连接池及事务控制 1.连接池 在实际开发中,都会使用连接池,因为它可以减少获取连接缩消耗的时间.所谓连接池,就是存储数据库连接的容器.连接池中存储一定数量的数据库连接,当线程需要使用 ...

  9. 游标、动态sql、异常

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlIAAAFeCAIAAADBl2bCAAAgAElEQVR4nOyddXgU197H12OEELxIkV

随机推荐

  1. 关于 Chrome 浏览器中 onresize 事件的 Bug

    我在写插件时用到了 onresize 事件,在反复地测试后发现该事件在 Chrome 及 Opera(内核基本与 Chrome 相同,以下统称 Chrome)浏览器打开时就会执行,这种情况也许不能算作 ...

  2. 探索ASP.NET MVC5系列之~~~2.视图篇(上)---包含XSS防御和异步分部视图的处理

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  3. jQuery学习之路(6)- 简单的表格应用

    ▓▓▓▓▓▓ 大致介绍 在CSS技术之前,网页的布局基本都是依靠表格制作,当有了CSS之后,表格就被很多设计师所抛弃,但是表格也有他的用武之地,比如数据列表,下面以表格中常见的几个应用来加深对jQue ...

  4. pt-mext

    pt-mext实现的功能比较简单,就是将mysqladmin输出的多次迭代的相同status变量值放到同一行输出. 参数很少,除了--help和--version外,只有一个--relative参数 ...

  5. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  6. [转载]强制不使用“兼容性视图”的HTML代码

    在IE8浏览器以后版本,都有一个"兼容性视图",让不少新技术无法使用.那么如何禁止浏览器自动选择"兼容性视图",强制IE以最高级别的可用模式显示内容呢?下面就介 ...

  7. 防线修建 bzoj 2300

    防线修建(1s 512MB)defense [问题描述] 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还 ...

  8. 树莓派 基于Web的温度计

    前言:家里的树莓派吃灰很久,于是拿出来做个室内温度展示也不错. 板子是model b型. 使用Python开发,web框架是flask,温度传感器是ds18b20 1 硬件连接 ds18b20的vcc ...

  9. 深入理解css3中nth-child和 nth-of-type的区别

    在css3中有两个新的选择器可以选择父元素下对应的子元素,一个是:nth-child 另一个是:nth-of-type. 但是它们到底有什么区别呢? 其实区别很简单::nth-of-type为什么要叫 ...

  10. Android Studio-—使用OpenCV的配置方法和demo以及开发过程中遇到的问题解决

    前提: 1.安装Android Studio(过程略) 2.官网下载OpenCV for Android 网址:http:opencv.org/downloads.html 我下载的是下图的版本 3. ...