统计sql审计系统中DML语句中UPDATE高频sql

1 创建sql_audit 表存储raw data

drop table if exists sql_audit;

CREATE TABLE `sql_audit` (

  `sql_info` longtext NOT NULL,
  `base` varchar(50) NOT NULL,
  `tablename` longtext,
  `field` varchar(200) DEFAULT NULL,
  `count` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2 从审计系统中导出近7天数据到sql_audit库表中
#获取raw data
insert into sql_audit(sql_info,base) select `db-ticket2`.`core_sqlrecord`.`sql`,`db-ticket2`.`core_sqlrecord`.`base` from `db-ticket2`.`core_sqlrecord` where  TO_DAYS(NOW()) - TO_DAYS(`db-ticket2`.`core_sqlrecord`.date) <= 7 and `db-ticket2`.`core_sqlrecord`.`sql` like 'UPDATE%';

3 创建存储过程
#存储过程sql_audit,实现获取每个update语句的tablename, field
drop PROCEDURE  if exists sql_audit;
DELIMITER ;;
CREATE DEFINER=`root`@`10.117.52.118` PROCEDURE `sql_audit`()
begin
declare pos1 int;#记录set位置
declare pos2 int;#记录=位置
declare pos3 int;#记录空格位置
declare sql_item longtext;
declare tablename VARCHAR(200);
declare stop int default 0; 

DECLARE cursor_select CURSOR FOR select sql_info from sql_audit; #因为要遍历select中的每一条记录,所以要用到游标,这里声明一个游标
declare CONTINUE HANDLER FOR SQLSTATE '02000' SET stop = null; 
OPEN cursor_select;
FETCH cursor_select INTO sql_item;
WHILE ( stop is not null) DO
set @pos1 = (select INSTR(sql_item,'set'));#获取sql_item中set所在的位置
    #set @tablename =  substring(sql_item, 7, @pos1-1);#取sql_item中从第7个字符到所set在位置之间的字符串,即tablename
    set @pos2 = (select INSTR(sql_item,'='));#获取sql_item中=所在的位置
if (locate('update',sql_item) > 0) then
set @pos3 = (select INSTR(replace(replace(sql_item,'UPDATE','update'),'update ',''),' '));
update sql_audit set  tablename = substring(sql_item, 7, @pos3),field = substring(sql_item, @pos1+4, @pos2-@pos1-4) where sql_info = sql_item;
elseif (locate('a inner',sql_item) > 0) then
set  @pos3 = (select locate('a inner',sql_item));
update sql_audit set  tablename = substring(sql_item, 7, @pos3-7),field = substring(sql_item, @pos1+4, @pos2-@pos1-4) where sql_info = sql_item;
elseif (locate('inner',sql_item) > 0) then
set  @pos3 = (select locate('inner',sql_item));
update sql_audit set  tablename = substring(sql_item, 7, @pos3-7),field = substring(sql_item, @pos1+4, @pos2-@pos1-4) where sql_info = sql_item;
end if;
COMMIT;     
    FETCH cursor_select INTO sql_item;#游标下移
END WHILE;
CLOSE cursor_select;
end;;
DELIMITER ;

4 存储过程调用
call sql_audit();

5 对结果集进行排序,并更新到表count字段
#更新count统计结果

update sql_audit a set a.count = (select b.count from (select tablename as tablename, field as field, count(*) as count from sql_audit group by tablename,field) b where a.field = b.field and a.tablename = b.tablename);


6 查询count统计结果

#查询count统计结果

select  distinct base,tablename,field, count from sql_audit order by count desc;

猜你喜欢

转载自blog.csdn.net/wangtingting_100/article/details/80265882
今日推荐