创建存储过程
创建固定模板
自定义部分解释:
p_xxx ---- 存储过程名称
(IN ... OUT ...)----存储过程入参出参(调用时出参需要在相同位置用参数@b来接收)
xxx为存储过程实际部分
DELIMITER //
CREATE PROCEDURE P_XXX(IN a varchar(x),OUT b int)
BEGIN
xxx
END
//
DELIMITER ;
❤ 动态SQL例子 ❤
sql需要用到动态变量时,基本使用动态SQL来执行需要执行的SQL,如下为基本固定写法:
-- 1 label关系表v_labellist 2 打标任务表v_batchlist 3本次打标标签表v_temptaglist
SET labellist_e = CONCAT(labellist,coalesce(epidtb,''));
SET temptaglist_e = CONCAT('temptaglist',coalesce(epidtb,''));
SET @SQL1 = CONCAT('create or replace view v_batchlist as select guid from ',batchlist,coalesce(epidtb,''));
SET @SQL2 = CONCAT('create or replace view v_temptaglist as select label_guid from ', temptaglist_e,' where tag = ''',temptag,'''');
PREPARE stmt FROM @SQL1; -- 预处理需要执行的动态SQL,其中stmt是一个变量
EXECUTE stmt; -- 执行SQL语句
DEALLOCATE PREPARE stmt; -- 释放掉预处理段
PREPARE stmt2 FROM @SQL2; -- 预处理需要执行的动态SQL,其中stmt是一个变量
EXECUTE stmt2; -- 执行SQL语句
DEALLOCATE PREPARE stmt2; -- 释放掉预处理段
❤ 游标例子 ❤
做循环就需要使用到游标,游标的基本固定写法也是如下:
DECLARE done int DEFAULT FALSE;
-- 1 循环出要打的customer-guid
DECLARE cur_labelid CURSOR FOR select label_guid from v_temptaglist;
OPEN cur_labelid;
read_loop: LOOP
-- 提取游标里的数据,这里只有一个,多个的话也一样;
FETCH cur_labelid INTO v_guid;
-- 声明结束的时候
IF done THEN
LEAVE read_loop;
END IF;
/*实际执行代码段位置*/
end LOOP;
close cur_labelid;
❤ 传参可能为null的参数 ❤
如果传参可能为null的参数,请完全使用以下写法替换,否则会报错的
把写参数epid的地方全部用coalesce(epidtb,'')替换
SET labellist_e = CONCAT(labellist,coalesce(epidtb,''));
成功调试出的创建存储过程例子
最后调试出来可运行的‘给客户批量贴标签’的存储过程实例
DELIMITER //
CREATE PROCEDURE jh.p_customerlabeling_batch(IN batchlist VARCHAR(50),IN labellist VARCHAR(50),temptag varchar(20),epidtb char(7),OUT result INT)
BEGIN
/*
2-1 取到所有参数 1打标表batchlist,2标签关系表labellist,3标签temptaglist的tag字段temptag,4epid 5 out result
2-2 取到要打的标guid列表v_xxx: temptaglist&tag
*/
-- declare v_int int;
declare v_guid char(36);
declare v_batchlist varchar(50);/*需要批量达标的视图名:表名+epid(eg:batchmarking_bytype20180928)*/
declare labellist_e varchar(50);/*打标关联表名+epid(eg:cutomerlabelo)*/
declare temptaglist_e varchar(50);/**/
declare v_temptaglist varchar(50);/*视图名:存储本次要打标的标签*/
DECLARE done int DEFAULT FALSE;
-- 1 循环出要打的customer-guid
DECLARE cur_labelid CURSOR FOR select label_guid from v_temptaglist;
-- 1 label关系表v_labellist 2 打标任务表v_batchlist 3本次打标标签表v_temptaglist
SET labellist_e = CONCAT(labellist,coalesce(epidtb,''));
SET temptaglist_e = CONCAT('temptaglist',coalesce(epidtb,''));
SET @SQL1 = CONCAT('create or replace view v_batchlist as select guid from ',batchlist,coalesce(epidtb,''));
SET @SQL2 = CONCAT('create or replace view v_temptaglist as select label_guid from ', temptaglist_e,' where tag = ''',temptag,'''');
PREPARE stmt FROM @SQL1; -- 预处理需要执行的动态SQL,其中stmt是一个变量
EXECUTE stmt; -- 执行SQL语句
DEALLOCATE PREPARE stmt; -- 释放掉预处理段
PREPARE stmt2 FROM @SQL2; -- 预处理需要执行的动态SQL,其中stmt是一个变量
EXECUTE stmt2; -- 执行SQL语句
DEALLOCATE PREPARE stmt2; -- 释放掉预处理段
OPEN cur_labelid;
read_loop: LOOP
-- 提取游标里的数据,这里只有一个,多个的话也一样;
FETCH cur_labelid INTO v_guid;
-- 声明结束的时候
IF done THEN
LEAVE read_loop;
END IF;
/*
2-2 取到要打的标guid列表v_xxx: temptaglist&tag
2-3 游标循坏guid----call proceduce (1customer_label列表-拼接好epid 2本次打标的label_guid )
*/
CALL p_customerlabeling_single(labellist_e,v_guid);
/*
delete from v_labellist where relation_guid = cur_guid and relation_labelid =
*/
set result = 1;
end LOOP;
close cur_labelid;
/*尾*/
END
//
DELIMITER ;
调试存储过程
神器 dbForge Studio for MySQL
官网:https://www.devart.com/dbforge/mysql/studio/editions.html
30天免费试用完全够够的
下载后连接上数据库,模拟传参,F10对存储过程进行一步步执行,可以看到哪一句产生报错。
并且可以通过watchs对变量进行查看
唯一有点不好的地方,是需要用root权限才能调试存储过程,连接公司存储过程失败了,只能dump到本机mysql进行调试。