SHOW_SPACE

CREATE OR REPLACE PROCEDURE SHOW_SPACE(P_SEGNAME   IN VARCHAR2
                                      ,P_OWNER     IN VARCHAR2 DEFAULT USER
                                      ,P_TYPE      IN VARCHAR2 DEFAULT 'TABLE'
                                      ,P_PARTITION IN VARCHAR2 DEFAULT NULL)
-- this procedure uses authid current user so it can query DBA_*
  -- views using privileges from a ROLE and so it can be installed
  -- once per database, instead of once per user that wanted to use it
AUTHID CURRENT_USER AS
  L_FREE_BLKS          NUMBER;
  L_TOTAL_BLOCKS       NUMBER;
  L_TOTAL_BYTES        NUMBER;
  L_UNUSED_BLOCKS      NUMBER;
  L_UNUSED_BYTES       NUMBER;
  L_LASTUSEDEXTFILEID  NUMBER;
  L_LASTUSEDEXTBLOCKID NUMBER;
  L_LAST_USED_BLOCK    NUMBER;
  L_SEGMENT_SPACE_MGMT VARCHAR2(255);
  L_UNFORMATTED_BLOCKS NUMBER;
  L_UNFORMATTED_BYTES  NUMBER;
  L_FS1_BLOCKS         NUMBER;
  L_FS1_BYTES          NUMBER;
  L_FS2_BLOCKS         NUMBER;
  L_FS2_BYTES          NUMBER;
  L_FS3_BLOCKS         NUMBER;
  L_FS3_BYTES          NUMBER;
  L_FS4_BLOCKS         NUMBER;
  L_FS4_BYTES          NUMBER;
  L_FULL_BLOCKS        NUMBER;
  L_FULL_BYTES         NUMBER;
  -- inline procedure to print out numbers nicely formatted
  -- with a simple label
  PROCEDURE P(P_LABEL IN VARCHAR2, P_NUM IN NUMBER) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE(RPAD(P_LABEL, 40, '.') ||
                         TO_CHAR(P_NUM, '999,999,999,999'));
  END;

BEGIN
  -- this query is executed dynamically in order to allow this procedure
  -- to be created by a user who has access to DBA_SEGMENTS/TABLESPACES
  -- via a role as is customary.
  -- NOTE: at runtime, the invoker MUST have access to these two
  -- views!
  -- this query determines if the object is a ASSM object or not
  BEGIN
    EXECUTE IMMEDIATE 'select ts.segment_space_management
from dba_segments seg, dba_tablespaces ts
where seg.segment_name = :p_segname
and (:p_partition is null or
seg.partition_name = :p_partition)
and seg.owner = :p_owner
and seg.tablespace_name = ts.tablespace_name'
      INTO L_SEGMENT_SPACE_MGMT
      USING P_SEGNAME, P_PARTITION, P_PARTITION, P_OWNER;
  EXCEPTION
    WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.PUT_LINE('This must be a partitioned table, use p_partition => ');
      RETURN;
  END;
  -- if the object is in an ASSM tablespace, we must use this API
  -- call to get space information, else we use the FREE_BLOCKS
  -- API for the user managed segments
  IF L_SEGMENT_SPACE_MGMT = 'AUTO' THEN
    DBMS_SPACE.SPACE_USAGE(P_OWNER
                          ,P_SEGNAME
                          ,P_TYPE
                          ,L_UNFORMATTED_BLOCKS
                          ,L_UNFORMATTED_BYTES
                          ,L_FS1_BLOCKS
                          ,L_FS1_BYTES
                          ,L_FS2_BLOCKS
                          ,L_FS2_BYTES
                          ,L_FS3_BLOCKS
                          ,L_FS3_BYTES
                          ,L_FS4_BLOCKS
                          ,L_FS4_BYTES
                          ,L_FULL_BLOCKS
                          ,L_FULL_BYTES
                          ,P_PARTITION);
    P('Unformatted Blocks ', L_UNFORMATTED_BLOCKS);
    P('FS1 Blocks (0-25) ', L_FS1_BLOCKS);
    P('FS2 Blocks (25-50) ', L_FS2_BLOCKS);
    P('FS3 Blocks (50-75) ', L_FS3_BLOCKS);
    P('FS4 Blocks (75-100)', L_FS4_BLOCKS);
    P('Full Blocks ', L_FULL_BLOCKS);
  ELSE
    DBMS_SPACE.FREE_BLOCKS(SEGMENT_OWNER     => P_OWNER
                          ,SEGMENT_NAME      => P_SEGNAME
                          ,SEGMENT_TYPE      => P_TYPE
                          ,FREELIST_GROUP_ID => 0
                          ,FREE_BLKS         => L_FREE_BLKS);
    P('Free Blocks', L_FREE_BLKS);
  END IF;
  -- and then the unused space API call to get the rest of the
  -- information
  DBMS_SPACE.UNUSED_SPACE(SEGMENT_OWNER             => P_OWNER
                         ,SEGMENT_NAME              => P_SEGNAME
                         ,SEGMENT_TYPE              => P_TYPE
                         ,PARTITION_NAME            => P_PARTITION
                         ,TOTAL_BLOCKS              => L_TOTAL_BLOCKS
                         ,TOTAL_BYTES               => L_TOTAL_BYTES
                         ,UNUSED_BLOCKS             => L_UNUSED_BLOCKS
                         ,UNUSED_BYTES              => L_UNUSED_BYTES
                         ,LAST_USED_EXTENT_FILE_ID  => L_LASTUSEDEXTFILEID
                         ,LAST_USED_EXTENT_BLOCK_ID => L_LASTUSEDEXTBLOCKID
                         ,LAST_USED_BLOCK           => L_LAST_USED_BLOCK);
  P('Total Blocks', L_TOTAL_BLOCKS);
  P('Total Bytes', L_TOTAL_BYTES);
  P('Total MBytes', TRUNC(L_TOTAL_BYTES / 1024 / 1024));
  P('Unused Blocks', L_UNUSED_BLOCKS);
  P('Unused Bytes', L_UNUSED_BYTES);
  P('Last Used Ext FileId', L_LASTUSEDEXTFILEID);
  P('Last Used Ext BlockId', L_LASTUSEDEXTBLOCKID);
  P('Last Used Block', L_LAST_USED_BLOCK);
END;

===============================================

分区表中的使用:

SQL> set serverout on
SQL> exec  show_space('TABLE_NAME,'OWNER','TABLE PARTITION','PARTITION_NAME');

 

 

 

posted @ 2012-03-20 19:23  wbzhao  阅读(392)  评论(0编辑  收藏  举报