MySQL存储过程使用嵌套游标

MySQL存储过程使用嵌套游标

存储过程简介

存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程可以简化应用开发
人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

特点
1.封装,复用 -----------------------> 可以把某一业务SQL封装在存储过程中,需要用到
的时候直接调用即可。
2.可以接收参数,也可以返回数据 --------> 再存储过程中,可以传递参数,也可以接收返回
值。
3.减少网络交互,效率提升 -------------> 如果涉及到多条SQL,每执行一次都是一次网络传
输。 而如果封装在存储过程中,我们只需要网络交互一次可能就可以了。

游标简介

游标(CURSOR)是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用游标对结果集进
行循环的处理

需求
使用存储过程将博客分类表与博客表数据迁移到category与blog表

博客分类表

CREATE TABLE `m_category` (
  `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `parent_id` bigint(32) unsigned DEFAULT NULL COMMENT '父级分类的ID',
  `name` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '标题',
  `content` text COLLATE utf8mb4_unicode_ci COMMENT '内容描述',
  `summary` text COLLATE utf8mb4_unicode_ci COMMENT '摘要',
  `icon` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图标',
  `order_num` int(11) DEFAULT NULL COMMENT '排序编码',
  `status` int(2) DEFAULT NULL COMMENT '状态',
  `create_by` bigint(32) DEFAULT NULL COMMENT '创建人',
  `create_time` datetime DEFAULT NULL COMMENT '创建日期',
  `update_by` bigint(32) DEFAULT NULL COMMENT '修改人',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='分类栏目';

INSERT INTO `m_category`(`id`, `parent_id`, `name`, `content`, `summary`, `icon`, `order_num`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (1, NULL, '提问', NULL, NULL, NULL, NULL, 0, NULL, '2020-04-28 22:36:48', NULL, NULL);
INSERT INTO `m_category`(`id`, `parent_id`, `name`, `content`, `summary`, `icon`, `order_num`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (2, NULL, '分享', NULL, NULL, NULL, NULL, 0, NULL, '2020-04-28 22:36:48', NULL, NULL);
INSERT INTO `m_category`(`id`, `parent_id`, `name`, `content`, `summary`, `icon`, `order_num`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (3, NULL, '讨论', NULL, NULL, NULL, NULL, 0, NULL, '2020-04-28 22:36:48', NULL, NULL);
INSERT INTO `m_category`(`id`, `parent_id`, `name`, `content`, `summary`, `icon`, `order_num`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (4, NULL, '建议', NULL, NULL, NULL, NULL, 0, NULL, '2020-04-28 22:36:48', NULL, NULL);

博客表

CREATE TABLE `m_blog` (
  `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `category_id` bigint(32) DEFAULT NULL COMMENT '分类栏目ID',
  `title` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '标题',
  `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '内容',
  `vote_up` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '支持人数',
  `vote_down` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '反对人数',
  `view_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '访问量',
  `status` int(2) DEFAULT NULL COMMENT '状态',
  `create_by` bigint(32) DEFAULT NULL COMMENT '创建人',
  `create_time` datetime DEFAULT NULL COMMENT '创建日期',
  `update_by` bigint(32) DEFAULT NULL COMMENT '修改人',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='博客表';

INSERT INTO `m_blog`(`id`, `category_id`, `title`, `content`, `vote_up`, `vote_down`, `view_count`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (1, 1, '一起学习Vue', '一起学习Vue吧', 0, 0, 5, NULL, NULL, '2020-04-28 14:41:41', NULL, '2020-04-28 14:41:41');
INSERT INTO `m_blog`(`id`, `category_id`, `title`, `content`, `vote_up`, `vote_down`, `view_count`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (2, 2, '一起学习Java', '一起学习Java吧', 0, 0, 3, NULL, NULL, '2020-04-28 14:55:16', NULL, '2020-04-28 14:55:16');
INSERT INTO `m_blog`(`id`, `category_id`, `title`, `content`, `vote_up`, `vote_down`, `view_count`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (3, 3, '一起学习Mysql', '一起学习Mysql吧', 0, 0, 1, NULL, NULL, '2020-04-28 14:55:48', NULL, '2020-04-28 14:55:48');

编写存储过程

DROP PROCEDURE tsblog;
CREATE PROCEDURE tsblog ( ) 
BEGIN
 -- 定义变量
	DECLARE cid int;
	DECLARE cname VARCHAR(50);
	DECLARE bcategory_id int;
	DECLARE btitle VARCHAR(50);
	DECLARE bcontent VARCHAR(50);
	DECLARE bcount int DEFAULT 0;
	DECLARE lable INT DEFAULT  0;
	-- 定义外部游标
	DECLARE category_cursor CURSOR FOR select id,name from m_category;
	-- 定义内部游标
	DECLARE blog_cursor CURSOR FOR select category_id,title,content from m_blog;
	-- 当出现NOT FOUND异常时,执行后面的语句
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET lable=1;
	-- 打开游标
	OPEN category_cursor;
	
	-- 创建博客分类表
	DROP table IF EXISTS category;
	create table if not exists category(
		cid int PRIMARY key auto_increment,
		cname VARCHAR(100)
	);
	
	-- 创建博客表
	DROP table IF EXISTS blog;
	create table if not exists blog(
		bid int PRIMARY key auto_increment,
		cid int,
		btitle VARCHAR(50),
		bname VARCHAR(100)
	);
	-- 读取外部游标数据
  category_loop: LOOP
		FETCH category_cursor into cid,cname;
		IF lable=1 THEN
			LEAVE category_loop;
		END IF;
		-- 获取category表插入的ID
		SET bcount := (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'myblog' AND TABLE_NAME = 'category');
		INSERT into category VALUES(null,cname);
		-- 打开内部游标
		OPEN blog_cursor;
		-- 读取内部游标数据
		blog_loop: LOOP
			FETCH blog_cursor into bcategory_id,btitle,bcontent;
			IF lable=1 THEN
			 LEAVE blog_loop;
			END IF;
			if bcategory_id=cid THEN
			    -- INSERT INTO  blog VALUES (null,(select max(cid) from category),btitle,bcontent);
				INSERT INTO  blog VALUES (null,bcount,btitle,bcontent);
			END IF;
		END LOOP blog_loop;
		-- 关闭内部游标
		CLOSE blog_cursor;
		-- 内部游标执行完,设置为0,继续执行外部游标
		SET lable=0;
  END LOOP category_loop;
	-- 关闭游标
	CLOSE category_cursor;
END;
CALL tsblog ();

你可能感兴趣的:(mysql,数据库)