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 ;
动态sql

 

 

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 ;
使用循环代码块

 

posted @ 2016-08-13 16:33  咖啡茶  阅读(99)  评论(0)    收藏  举报