秋天的第一个存储过程

问题描述:创建性能监测表。从数据库中找出 num_rows<=3,或者统计信息被锁定的表;并且把这些表count(*)的历史峰值,记录下来。使用定时任务加上存储过程来实现这个方式,先筛选符合条件的信息,然后把这些信息存入性能监测表MONITORING_STATISTIC;然后对这些表中得数据进行分析。

1.创建数据存储表

 

create table MONITORING_STATISTIC
(
  id                number generated by default as identity,
  owner             VARCHAR2(128),
  table_name        VARCHAR2(128),
  num_rows          NUMBER,
  object_type       VARCHAR2(12),
  stattype_locked   VARCHAR2(5),
  max_counts        NUMBER,  --初始设置成num_rows
  last_changed_time TIMESTAMP(6)  --设置成空
);

comment on column monitoring_statistic.stattype_locked is '锁定状态';
comment on column monitoring_statistic.max_counts is 'count*历史最大值';
comment on column monitoring_statistic.last_changed_time is '插入时间';

alter table monitoring_statistic add  primary key(id);

 

2.初始化基表

如果要再次初始化最好truncate基表,要不然会插入重复数据
create table monitoring_statistic_XX;
truncate table monitoring_statistic;

插入初始数据
insert into monitoring_statistic(owner,table_name,num_rows,object_type,stattype_locked,max_counts) 
select b.*,b.num_rows
from (
select t.owner, t.table_name,NVL(t.num_rows,0) num_rows,a.object_type,a.stattype_locked  from dba_tables t,DBA_TAB_STATISTICS a 
where (t.num_rows <= 3 or t.num_rows = 100) and t.OWNER not IN(select username from dba_users where ORACLE_MAINTAINED = 'Y')  
and t.table_name = a.table_name and t.owner=a.owner
union
select t.owner, t.table_name,NVL(t.num_rows,0) num_rows,a.object_type,a.stattype_locked from DBA_TAB_STATISTICS a,dba_tables t
where a.stattype_locked IN ('ALL', 'DATA', 'CACHE') and a.OWNER not IN(select username from dba_users where ORACLE_MAINTAINED = 'Y')
and t.table_name = a.table_name and t.owner=a.owner) b;
commit;

 

3.查询基表数据

col id for 999999
col table_name for a20
col partition_name for a10
col num_rows for 999999
col object_type for a20
col stattype_locked for a15
col max_counts for 999999
col last_changed_time for a30
col owner for a30
set linesize 999

select * from monitoring_statistic;

 

4.创建存储过程,如果使用的其他用户,要写明用户名

CREATE OR REPLACE PROCEDURE "ZHIHENGHOU"."PROC_GATHER_STAT_COUNTS"
as 
    t_count number; 
    t_num_rows number;
    t_tablename varchar2(50);
    t_owner varchar2(50);
    t_max_counts number;   --表历史最大count值
    t_sql varchar2(200);   --查询到的每个表的count*值
    m_count number;        --monitoring_statistic表行数
    t_cs int;           --循环计数器   
    CURSOR c1 IS select owner,table_name,num_rows,max_counts from ZHIHENGHOU.monitoring_statistic;   --把需要的字段筛选出来
begin
    select count(*) into m_count from ZHIHENGHOU.monitoring_statistic;
    t_cs := 0;
    FOR x IN c1 LOOP
        t_tablename := x.TABLE_NAME;
        t_num_rows := x.num_rows;
        t_owner := x.owner;
        t_max_counts := x.max_counts;
        t_sql :='select count(*) from '||t_owner||'.'||t_tablename;                        
        Execute immediate t_sql into  t_count ;
        if  t_count > t_max_counts then
            update ZHIHENGHOU.monitoring_statistic set max_counts=t_count,last_changed_time=sysdate where table_name=t_tablename and owner=t_owner;
            commit;
        END IF;
        t_cs := t_cs+1;
        DBMS_OUTPUT.PUT_LINE('The '||t_cs||' table is being checked,There are '||m_count||' tables in total!');
        END LOOP;
END;
/

 

5.调用存储过程

set serveroutput on
call PROC_GATHER_STAT_COUNTS();

 

 

 

 6.查询监测表,如果表的count(*) 发生变化,将会被更新,记录更新时间

 

 

 

7.可配合定时任务使用

 

 

8.执行过程中的报错,使用其他具有DBA用户创建存储过程,执行存储过程失败,提示权限不足

是因为存储过程中Execute immediate t_sql into t_count ; Execute immediate需要在授予相关的权限

GRANT
   CREATE SESSION,
    CREATE ANY TABLE,
    ALTER ANY TABLE,
   SELECT ANY TABLE,
    INSERT ANY TABLE,
    UPDATE ANY TABLE,
    DELETE ANY TABLE
TO ZHIHENGHOU;

 

 

Tags: