存储过程简介
存储过程是事先经过编译并存储在数据库中的一段 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 ();