以前使用sql只是简单的增、删、改、查,最多加些内联外联,但是在工作中遇到一个sql,不适用循环是根本写不出来,后来研究了下,把自己碰到的坑分享一下,自己也是第一次写博客。
写这个语句的需求是:
将一个查询的结果集作为模糊匹配的条件,并且这个表名并不确定,需要传入表名,这个是写的过程中最痛苦的。在网上找了半天也没找到。
- 首先我们需要创建一个能传入参数的存储过程
DROP PROCEDURE IF EXISTS `proc_while`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_while`(IN table_name
- 定义一些自己需要的参数,这些参数都要写在开始位置,最好不要随便乱放,自己就是因为习惯于java语言,所以之前就碰到很多问题。
BEGIN
#Routine body goes here...
DECLARE vID VARCHAR(500);
DECLARE done INT DEFAULT 0;
DECLARE s int DEFAULT 1;
- 对于游标,游标后面只能跟着select ····· from ·····,但是由于自己的表名是传进来的,所以是需要拼接,那么直接使用正常的是行不通的
DECLARE cur CURSOR FOR SELECT ID FROM v_view;#通过查询视图
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
#通过拼接sql,并且将sql执行,这个用到了创建视图v_view ,然后将视图作为游标查询的表
set @sql =concat(" create view v_view as select b.ID from ", table_name," b where b.ID not in (select a.ID from ",table_name ," a )");
#这个地方就是将拼接sql执行
DROP VIEW IF EXISTS v_view;
PREPARE stmt1 FROM @sql;
EXECUTE stmt1 ;
DEALLOCATE PREPARE stmt1;
- 然后就是使用游标,取出里面的值
OPEN cur ;#打开游标
FETCH cur into vID ;#将游标中的值付给vID,这里类似于java中的迭代。
WHILE s <= 6 DO
·
·
·
FETCH cur into vID ;#循环后再次付值
END WHILE;
CLOSE cur ;
- 写的过程语句的位置最好不要随意改,自己就是在这里耗了很长时间,有些地方不要忘记 分号(;),都是自己遇到的坑。
-- ----------------------------
-- Procedure structure for `proc_while`
-- ----------------------------
DROP PROCEDURE IF EXISTS `proc_while`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_while`(IN table_name VARCHAR(500))
BEGIN
#Routine body goes here...
DECLARE vID VARCHAR(500);
DECLARE done INT DEFAULT 0;
DECLARE s int DEFAULT 1;
DECLARE cur CURSOR FOR SELECT ID FROM v_view;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
set @sql =concat(" create view v_view as select b.ID from ", table_name," b where b.ID not in (select a.ID from ",table_name ," a )");
DROP VIEW IF EXISTS v_view;
PREPARE stmt1 FROM @sql;
EXECUTE stmt1 ;
DEALLOCATE PREPARE stmt1;
OPEN cur ;
FETCH cur into vID ;
WHILE s <= 6 DO
set @updatesql = concat("select c.id from ", table_name," c where c.CCID like CONCAT('%/','",vID ,"','/%')");
PREPARE updatestmt FROM @updatesql;
EXECUTE updatestmt ;
DEALLOCATE PREPARE updatestmt;
set s = s + 1;
FETCH cur into vID ;
END WHILE;
CLOSE cur ;
END
;;
DELIMITER ;
第一次写,如果有啥不对的请大神们指点一下,对于技术自己还是菜鸟,只是想找个能记录自己学习的过程和分享一些自己遇到的坑。