Mysql-存储过程
1: 使用游标
1 DELIMITER ;; 2 CREATE DEFINER=`root`@`%` PROCEDURE `cq_c1_mal_rips`(IN search_time VARCHAR(20),IN search_domains TEXT 3 ,IN startIndex INT,IN pageSize INT,OUT return_total INT) 4 BEGIN 5 DECLARE rip_total INT; # RIP数量 6 DECLARE v_rip VARCHAR(4000); #存储RIP 7 DECLARE num INT DEFAULT 1; # 循环使用的变量 8 DECLARE tempDetailSql TEXT; 9 #定义游标遍历时,作为判断是否遍历完全部记录的标记 10 DECLARE no_more_departments INTEGER DEFAULT 0; 11 DECLARE cur_detail CURSOR FOR 12 SELECT rip_num,rip FROM c1_temp_mal_detail; 13 #声明当游标遍历完全部记录后将标志变量置成某个值 14 DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_departments=1; 15 DROP TABLE IF EXISTS c1_temp_mal_detail; 16 SET @tempDetailSql = CONCAT('CREATE TEMPORARY TABLE c1_temp_mal_detail(' 17 ,' SELECT LENGTH(rip)-LENGTH(REPLACE(rip, ",", "")) + 1 rip_num,rip' 18 ,' FROM `mal_domains_detail`' 19 ,' WHERE `date` = ',search_time,'' 20 ,' AND domain IN (',search_domains,'))'); 21 PREPARE stmt FROM @tempDetailSql; 22 EXECUTE stmt; 23 DEALLOCATE PREPARE stmt; 24 #创建临时表 25 DROP TABLE IF EXISTS temp_mal_rips; 26 CREATE TEMPORARY TABLE temp_mal_rips ( 27 temp_rip VARCHAR(512) NOT NULL 28 ); 29 OPEN cur_detail; 30 REPEAT 31 FETCH cur_detail INTO rip_total, v_rip; 32 WHILE num<= rip_total DO 33 #临时表插入数据 34 INSERT INTO temp_mal_rips(temp_rip) VALUES(SUBSTRING_INDEX(SUBSTRING_INDEX(v_rip, ',', num),',',-1)); 35 SET num=num+1; 36 END WHILE; 37 SET num=1; 38 UNTIL no_more_departments END REPEAT;#循环结束 39 CLOSE cur_detail; 40 41 SELECT COUNT(distinct(temp_rip)) INTO return_total FROM temp_mal_rips; 42 43 SELECT (@i:=@i+1) AS lnum,a.temp_rip ip,'rip' `type` FROM 44 ( 45 SELECT temp_rip FROM temp_mal_rips GROUP BY temp_rip ORDER BY INET_ATON(temp_rip) 46 ) a,(SELECT @i:=startIndex) AS it 47 LIMIT startIndex,pageSize; 48 DROP TEMPORARY TABLE c1_temp_mal_detail; 49 DROP TEMPORARY TABLE temp_mal_rips; 50 END ;;
2:未使用游标
1 DELIMITER ;; 2 CREATE DEFINER=`root`@`%` PROCEDURE `PD_ddos_indicator_attacksource`( 3 in in_dip varchar(20),IN in_begintime VARCHAR(30),IN in_endtime VARCHAR(30), IN `pageNum` INT, IN `pageSize` INT,OUT `total` INT) 4 BEGIN 5 DECLARE num1 INT; 6 SELECT COUNT(1) INTO total 7 FROM dns_m_ddos_relation 8 WHERE dip = in_dip 9 AND DATETIME >= in_begintime 10 AND DATETIME <= in_endtime; 11 12 SELECT (pageNum-1)*pageSize INTO num1; 13 14 SELECT sip_city as 区县, 15 sip AS 攻击IP, 16 ROUND(SUM(VALUE*10)/(1024),2) AS 流量 17 FROM dns_m_ddos_relation 18 WHERE dip = in_dip 19 AND DATETIME >= in_begintime 20 AND DATETIME <= in_endtime 21 GROUP BY sip 22 ORDER BY VALUE DESC 23 LIMIT num1, pageSize; 24 END ;; 25 DELIMITER ;
3: 使用临时表
1 DELIMITER ;; 2 CREATE DEFINER=`root`@`%` PROCEDURE `PD_mal_test`(in v_rip varchar(20), in begin_time varchar(20)) 3 BEGIN 4 5 declare total int; # 域名数量 6 declare v_domain varchar(4000); #存储域名 7 declare aa int default 1; # 循环使用的变量 8 9 drop table if exists temp_domains; 10 11 CREATE TEMPORARY TABLE temp_domains ( 12 temp_domain varchar(255) not null , 13 temp_rip varchar(20) not null 14 ); 15 16 17 18 select LENGTH(domain)-LENGTH(REPLACE(domain, ',', '')) + 1 , domain into total , v_domain # 将域名数量和 域名字符串赋值给 变量 19 from mal_rips_result 20 where rip = v_rip 21 and date = date_format(begin_time, '%Y%m%d'); 22 23 # select total, v_domain; 24 25 26 # 开始循环体,将截取的域名,插入到临时表中 27 truncate table temp_domains; 28 29 WHILE aa<= total DO 30 31 #select v_rip,SUBSTRING_INDEX(SUBSTRING_INDEX(v_domain, ',', aa),',',-1) as size; 32 33 insert into temp_domains(temp_rip,temp_domain) values( v_rip,SUBSTRING_INDEX(SUBSTRING_INDEX(v_domain, ',', aa),',',-1));#临时表插入数据 34 35 #SELECT temp_rip, temp_domain FROM temp_domains; 36 37 SET aa=aa+1; 38 39 END WHILE; 40 41 42 select a.temp_domain, b.dgatype 43 from temp_domains a 44 inner join (select domain, dgatype from mal_domains_raw 45 where DATE = DATE_FORMAT(begin_time, '%Y%m%d')) b 46 on a.temp_domain = b.domain ; #从临时表查询数据 */ 47 END ;; 48 DELIMITER ;
4:使用用户变量
1 DELIMITER ;; 2 CREATE DEFINER=`root`@`%` PROCEDURE `PD_traff_attackedcycle`(IN v_id VARCHAR(50),IN v_total VARCHAR(20)) 3 BEGIN 4 5 /* 6 作者:闫菁 7 本过程用来获得 异常流量-异常流量首页, 攻击环图数据。 8 9 v_id: 从被攻击表格传递的eventiid。 10 v_total:从被攻击表格传递的总攻击流量 11 12 */ 13 14 #DECLARE attack_total DECIMAL(38,2); 15 DECLARE attack_top5 float(10,2); 16 17 #select CAST(v_total AS DECIMAL) into attack_total; #将传递总流量转化为数字 18 #select v_total into attack_total; 19 #select v_total,attack_total; 20 21 select sum(value) into attack_top5 #得到TOP5的总流量 22 from ( SELECT IF( NATION ='非洲','埃及',NATION) AS NAME, ROUND(SUM(IPFLOW),2) AS VALUE 23 FROM cradar1.traff_i_attackedtop20 24 WHERE eventid = v_id 25 GROUP BY NAME 26 ORDER BY VALUE DESC 27 LIMIT 5) top5; 28 29 30 SELECT ORD, NAME, VALUE, CONCAT(NAME,'流量:', VALUE, ' GB') AS info 31 FROM 32 ( SELECT ORD ,NAME, VALUE #得到TOP5的国家流量和排名 33 FROM 34 ( 35 SELECT @num := (@num +1) AS ORD, IF( NATION ='非洲','埃及',NATION) AS NAME, ROUND(sum(IPFLOW),2) AS VALUE 36 FROM cradar1.traff_i_attackedtop20 ,( SELECT @num :=0 )t 37 WHERE eventid = v_id 38 group by name 39 ORDER BY VALUE DESC 40 LIMIT 5 ) result1 41 42 UNION all 43 44 45 SELECT 6 AS ORD, '其他' AS NAME ,ROUND( v_total - IFNULL(attack_top5,0),2) AS VALUE 46 47 ) A; 48 49 50 END ;;
5: 使用分页查询
1 DELIMITER ;; 2 CREATE DEFINER=`root`@`%` PROCEDURE `PD_traff_attacklist`(IN in_eventid VARCHAR(50),IN pageNum INT, IN pageSize INT,OUT total INT) 3 BEGIN 4 5 /* 6 作者:闫菁 7 本过程用来获得 异常流量-异常流量首页,被攻击信息列表数据。 8 9 begin_time: 从时间轴传递的开始时间。 10 endt_ime:从时间轴传递的结束时间。 11 total: 传递给产品工厂的,输出总得表格条目数量。 12 pageSize: 产品工厂,分页表格应用的每页条目数量。 13 pageNum: 产品工厂,分页表格应用的总页面数量。 14 */ 15 16 DECLARE num1 INT; 17 18 19 SELECT COUNT(src_ip) INTO total 20 FROM cradar1.traff_i_attackedmsg 21 WHERE eventid = in_eventid; #获得选择的事件,攻击信息数量,并传递给total 输出变量 22 23 24 SELECT (pageNum-1)*pageSize INTO num1; # 或者 limit 分页的开始数据条目 25 26 SELECT src_ip AS 攻击IP, NATION AS 攻击地址, 27 #DATE_FORMAT(beg_time,'%y-%m %H:%i:%s') AS 开始时间,DATE_FORMAT(end_time,'%y-%m %H:%i:%s') AS 结束时间, 28 CONCAT(CAST(ROUND(IPFLOW,2) AS CHAR), 'GB') AS 攻击流量 29 FROM cradar1.traff_i_attackedmsg 30 WHERE eventid = in_eventid 31 ORDER BY ROUND(IPFLOW,2) DESC 32 LIMIT num1, pageSize; #查询符合要求的数据,并使用limit,返回分页的数据 33 34 35 END ;; 36 DELIMITER ;
6:使用动态sql
1 DELIMITER $$ 2 3 USE `nms`$$ 4 5 DROP PROCEDURE IF EXISTS `nms_version_app_detail`$$ 6 7 CREATE DEFINER=`root`@`%` PROCEDURE `nms_version_app_detail`(IN v_date VARCHAR(20),IN in_app VARCHAR(50),IN in_type VARCHAR(10),IN in_input VARCHAR(255),IN in_sysid VARCHAR(50),IN pageNum INT, IN pageSize INT,OUT total INT) 8 BEGIN 9 /* 10 本产品为 版本对比监测页面的表格 11 IN v_date VARCHAR(20) 查询时间, 12 IN in_app varchar(50) 下拉框应用id,value = 0为全部 13 IN in_type varchar(10) 单选框选项id,版本号字段为0, MD5为1,IP为2 14 IN in_input varchar(255) 文本框输入内容 15 IN in_sysid varchar(50) 系统权限id 16 情况分为: 17 1、应用为全部,选择项任意,输入框为空 (查询结果多合一) 18 2、应用为全部,选择MD5,输入框输入MD5 (查询结果为单独数据) 19 3、应用为全部,选择IP,输入框输入IP (查询结果多合一) 20 4、应用为独立应用,输入框为空 (查询结果多合一) 21 5、应用为独立应用,选择MD5,输入框输入MD5 (查询结果为单独数据) 22 6、应用为独立应用,选择IP,输入框输入IP (查询结果为单独数据) 23 */ 24 #1、选择了具体的应用,在查询条件中拼接查询条件。 25 DECLARE vv_input VARCHAR(255); #文本输入框去空格 26 DECLARE begin_time DATETIME; #开始时间 27 DECLARE end_time DATETIME; #结束时间 28 DECLARE where_appname VARCHAR(500); #app名称 条件 29 DECLARE where_policy_no VARCHAR(500); # 版本条件 30 DECLARE where_md5_result VARCHAR(500); #md5条件 31 DECLARE where_ip VARCHAR(500); #ip条件 32 DECLARE v_info VARCHAR(500); #info 33 DECLARE v_sql_base VARCHAR(1000); 34 DECLARE v_total VARCHAR(500); 35 DECLARE v_sql VARCHAR(1000); 36 DECLARE v_select1 VARCHAR(1000); 37 DECLARE v_select2 VARCHAR(1000); 38 DECLARE v_sql_limit VARCHAR(100); 39 DECLARE sum1 INT; 40 SET where_appname = ''; 41 SET where_policy_no = ''; 42 SET where_md5_result = ''; 43 SET where_ip = ''; 44 SELECT (pageNum-1)*pageSize INTO sum1; 45 46 IF v_date = '' THEN SET v_date = '2099-01-01'; 47 END IF; 48 49 SELECT CONCAT(v_date, ' 00:00:00'), CONCAT(v_date, ' 23:59:59') INTO begin_time, end_time; 50 51 52 #拼接应用名称 53 IF in_app != '0' THEN SET where_appname = CONCAT( ' and app_name = ', '''', in_app , ''''); 54 END IF; 55 #拼接版本号码 56 IF in_type = '0' THEN 57 IF vv_input != '' THEN SET where_policy_no = CONCAT( ' and policy_no = ', '''', vv_input , ''''); 58 END IF; 59 60 61 #拼接MD5 62 ELSEIF in_type = '1' THEN 63 IF vv_input != '' THEN SET where_md5_result = CONCAT( ' and md5_result = ', '''', vv_input , ''''); 64 65 END IF; 66 67 #拼接ip条件 68 ELSEIF in_type = '2' THEN 69 IF vv_input != '' THEN SET where_ip = CONCAT( ' and ip = ', '''', vv_input , ''''); 70 71 END IF; 72 END IF; 73 SET v_select1 = CONCAT(' select count(1) into @ret_total '); 74 SET v_select2 = CONCAT(' select app_name as ', '''', '应用名称','''', ' , ip as','''', '服务器IP','''', ' , Md5_result as ' ,'''','MD5值','''', 75 ',case when result = 1 then ','''','版本一致','''',' when result = 0 then ','''','版本不一致' ,'''', 76 ' else ','''','获取失败','''',' end as ','''','对比结果',''''); 77 78 79 #拼接查询sqlbase条件 80 SET v_sql_base = CONCAT( 81 ' 82 from nms_file_md5_m_info_his 83 where 1=1 84 and file_type = ','''','4','''',' 85 and app_class = ( select sys_name from nms_tb_sys where id = ','''', in_sysid, '''',' ) 86 and create_time >= ' ,'''',begin_time,'''',' and create_time <= ','''',end_time,'''') ; 87 88 89 90 91 SET v_sql_limit = CONCAT(' limit ', sum1, ' , ', pageSize ); 92 93 #拼接产品工厂全部条件 94 SET v_total = CONCAT(v_select1, v_sql_base, where_appname, where_policy_no,where_md5_result, where_ip); 95 SET v_sql = CONCAT(v_select2, v_sql_base, where_appname, where_policy_no,where_md5_result, where_ip,v_sql_limit); 96 97 98 99 100 SET @v_sql1 = v_total; #注意很重要,将连成成的字符串赋值给一个变量(可以之前没有定义,但要以@开头) 101 PREPARE stmt1 FROM @v_sql1; #--预处理需要执行的动态SQL,其中stmt是一个变量 102 EXECUTE stmt1 ; #--执行SQL语句 103 DEALLOCATE PREPARE stmt1; # --释放掉预处理段 104 SET total = @ret_total; 105 SET @v_sql2 = v_sql; #注意很重要,将连成成的字符串赋值给一个变量(可以之前没有定义,但要以@开头) 106 PREPARE stmt2 FROM @v_sql2; #--预处理需要执行的动态SQL,其中stmt是一个变量 107 EXECUTE stmt2 ; #--执行SQL语句 108 DEALLOCATE PREPARE stmt2; # --释放掉预处理段 109 SELECT v_total; 110 111 END$$ 112 113 DELIMITER ;
7:使用循环代码块
1 DELIMITER ;; 2 CREATE DEFINER=`root`@`%` PROCEDURE `test`() 3 BEGIN 4 DECLARE aa INT ; 5 SET aa=1; 6 WHILE aa<100 DO 7 INSERT INTO traff_i_attackedmsg (id,eventid,beattack_ip,src_ip,src_province,src_nation,bags,ipflow, beg_time,end_time) 8 (SELECT 10+round(rand()*1000,0),2,'192.168.1.4',src_ip,src_province,src_nation,bags,ROUND(RAND()*100,2),adddate( beg_time, interval - 3 hour),end_time 9 FROM traff_i_attackedmsg ); 10 11 SET aa=aa+1; 12 END WHILE; 13 END ;; 14 DELIMITER ;

浙公网安备 33010602011771号