暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle获取表统计信息脚本分享

DBA闲思杂想录 2026-01-16
64

这两个脚本是Kerry Osborne分享的脚本, 经常会用到这两个脚本,是非常实用的SQL脚本.分享于此.希望对你有用.

脚本table_stats.sql

    rem $Header$
    rem $Name$
    rem Copyright (c); 2004 by Hotsos Enterprises, Ltd.
    rem
    rem Retrieve statistics information for a table
    rem
    rem Usage:  SQL>@hstats <table name>
    rem
    --
    -- Modified by Kerry Osborne
    -- commented out Histogram section
    -- added prompts
    -- added ability to run against table in another schmea
    set echo off feed off
    set serveroutput on size 1000000
     accept ownname prompt 'Owner : '
     accept tabname prompt 'Table : '
    set lines 80
    define v_desc = '&ownname..&tabname.'
    desc &v_desc
    set lines 200
    declare
      v_query varchar2(4000)  ;
      v_owner varchar2(30) := upper('&&ownname');
      v_table varchar2(30) := upper('&&tabname');
      v_max_colname   number ;
      v_max_ndv               number ;
      v_max_nulls     number ;
      v_max_bkts      number ;
      v_max_smpl      number ;
      v_max_endnum    number ;
      v_max_endval    number ;
      v_ct                    number ;
      prev_col                varchar2(30) ;
      cursor col_stats is
      select a.column_name, nvl(a.last_analyzed,to_date('01/01/1900','mm/dd/yyyy')) last_analyzed,
                     decode(a.nullable,'N','NOT NULL','        ') nullable,
                     a.num_distinct, a.density, a.num_nulls,
             a.num_buckets, a.avg_col_len, a.sample_size
        from all_tab_columns a
       where a.owner = v_owner
         and a.table_name = v_table ;
      cursor hist_stats is
      select b.column_name, b.endpoint_number, b.endpoint_value, b.endpoint_actual_value
            from all_tab_histograms b
       where b.owner = v_owner
             and b.table_name = v_table
             and (exists (select 1 from all_tab_columns
                               where num_buckets > 1
                                 and owner = b.owner
                                 and table_name = b.table_name
                                 and column_name = b.column_name)
                      or
                      exists (select 1 from all_tab_histograms
                               where endpoint_number > 1
                                 and owner = b.owner
                                 and table_name = b.table_name
                                 and column_name = b.column_name)
                     )
            order by b.column_name, b.endpoint_number;
            procedure print_table ( p_query in varchar2,  p_date_fmt in varchar2 default 'dd-MON-yyyy hh24:mi:ss' ) is
                        l_theCursor     integer default dbms_sql.open_cursor;
                        l_columnValue   varchar2(4000);
                        l_status        integer;
                        l_descTbl       dbms_sql.desc_tab;
                        l_colCnt        number;
                        l_cs            varchar2(255);
                        l_date_fmt      varchar2(255);
                        -- Small inline procedure to restore the session's state.
                        -- We may have modified the cursor sharing and nls date format
                        -- session variables. This just restores them.
                        procedure restore
                        is
                        begin
                           if ( upper(l_cs) not in ( 'FORCE','SIMILAR' ))
                           then
                               execute immediate
                               'alter session set cursor_sharing=exact';
                           end if;
                           if ( p_date_fmt is not null )
                           then
                               execute immediate
                                   'alter session set nls_date_format=''' || l_date_fmt || '''';
                           end if;
                           dbms_sql.close_cursor(l_theCursor);
                        end restore;
                    begin
                        -- I like to see the dates print out with times, by default. The
                        -- format mask I use includes that.  In order to be "friendly"
                        -- we save the current session's date format and then use
                        -- the one with the date and time.  Passing in NULL will cause
                        -- this routine just to use the current date format.
                        if ( p_date_fmt is not null )
                        then
                           select sys_context( 'userenv', 'nls_date_format' )
                             into l_date_fmt
                             from dual;
                           execute immediate
                           'alter session set nls_date_format=''' || p_date_fmt || '''';
                        end if;
                        -- To be bind variable friendly on ad-hoc queries, we
                        -- look to see if cursor sharing is already set to FORCE or
                        -- similar. If not, set it to force so when we parse literals
                        -- are replaced with binds.
                        if ( dbms_utility.get_parameter_value
                             ( 'cursor_sharing', l_status, l_cs ) = 1 )
                        then
                            if ( upper(l_cs) not in ('FORCE','SIMILAR'))
                            then
                                execute immediate
                               'alter session set cursor_sharing=force';
                            end if;
                        end if;
                        -- Parse and describe the query sent to us.  We need
                        -- to know the number of columns and their names.
                        dbms_sql.parse(  l_theCursor,  p_query, dbms_sql.native );
                        dbms_sql.describe_columns
                        ( l_theCursor, l_colCnt, l_descTbl );
                        -- Define all columns to be cast to varchar2s. We
                        -- are just printing them out.
                        for i in 1 .. l_colCnt loop
                            dbms_sql.define_column
                            (l_theCursor, i, l_columnValue, 4000);
                        end loop;
                        -- Execute the query, so we can fetch.
                        l_status := dbms_sql.execute(l_theCursor);
                        -- Loop and print out each column on a separate line.
                        -- Bear in mind that dbms_output prints only 255 characters/line
                        -- so we'll see only the first 200 characters by my design...
                        while ( dbms_sql.fetch_rows(l_theCursor) > 0 )
                        loop
                            for i in 1 .. l_colCnt loop
                                dbms_sql.column_value
                                ( l_theCursor, i, l_columnValue );
                                dbms_output.put_line
                                ( rpad( l_descTbl(i).col_name, 30 )
                                  || ': ' ||
                                  substr( l_columnValue, 1, 200 ) );
                            end loop;
                            dbms_output.put_line( '-----------------' );
                        end loop;
                        -- Now, restore the session state, no matter what.
                        restore;
                    exception
                        when others then
                            restore;
                            raise;
                    end;
    begin
      dbms_output.put_line('==========================================================================================');
      dbms_output.put_line('  Table Statistics');
      dbms_output.put_line('==========================================================================================');
      v_query := 'select table_name, last_analyzed, trim(degree) degree, partitioned,
                                     num_rows, chain_cnt, blocks, empty_blocks, avg_space,
                                     avg_row_len, monitoring, sample_size
                                from all_tables
                               where owner = ''' || UPPER(v_owner) || ''' and table_name = ''' || UPPER(v_table) || '''';
      print_table (v_query);
      v_ct := 0 ;
      select count(1)
        into v_ct
            from all_tab_partitions
       where table_owner = v_owner
         and table_name = v_table;
      if v_ct > 0 then
              dbms_output.put_line('==========================================================================================');
              dbms_output.put_line('  Partition Information');
              dbms_output.put_line('==========================================================================================');
              v_query := 'select partition_name, last_analyzed, high_value,
                                             num_rows, chain_cnt, blocks, empty_blocks,
                                             avg_space, avg_row_len
                                            from all_tab_partitions
                                       where table_owner = ''' || UPPER(v_owner) || '''
                                         and table_name = ''' || UPPER(v_table) || '''';
              print_table (v_query);
      end if ;
      select max(length(column_name)) + 1, max(length(num_distinct)) + 3,
                     max(length(num_nulls)) + 1, max(length(num_buckets)) + 1,
                     max(length(sample_size)) + 1
        into v_max_colname, v_max_ndv, v_max_nulls, v_max_bkts, v_max_smpl
        from all_tab_columns
       where owner = v_owner
         and table_name = v_table ;
      if v_max_nulls < 8 then
         v_max_nulls := 8 ;
      end if ;
      if v_max_bkts < 10 then
         v_max_bkts := 10 ;
      end if ;
      if v_max_smpl < 7 then
         v_max_smpl := 7;
      end if;
      dbms_output.put_line('==========================================================================================');
      dbms_output.put_line('  Column Statistics');
      dbms_output.put_line('==========================================================================================');
      dbms_output.put_line(' ' || rpad('Name',v_max_colname) || '  Analyzed    Null?    ' ||
                    rpad(' NDV',v_max_ndv) || '  ' || rpad(' Density',10) ||
                    rpad('# Nulls',v_max_nulls) || '  ' || rpad('# Buckets',v_max_bkts) || '  ' ||
                    rpad('Sample',v_max_smpl) || '  Avg Col Len');
      dbms_output.put_line('==========================================================================================');
      for v_rec in col_stats loop
          dbms_output.put_line(rpad(v_rec.column_name,v_max_colname) || '  ' ||
          to_char(v_rec.last_analyzed,'mm/dd/yyyy') || '  ' ||
          v_rec.nullable || '  ' ||
          rpad(v_rec.num_distinct,v_max_ndv) ||
          to_char(v_rec.density,'9.999999') || '  ' ||
          rpad(v_rec.num_nulls,v_max_nulls) || '  ' ||
          rpad(v_rec.num_buckets,v_max_bkts) || '  ' ||
          rpad(v_rec.sample_size,v_max_smpl) || '  ' ||
          v_rec.avg_col_len );
      end loop ;
      select max(length(column_name)) + 1, max(length(endpoint_number)) + 1,
                     max(length(endpoint_value)) + 1
        into v_max_colname, v_max_endnum, v_max_endval
        from all_tab_histograms
       where owner = v_owner
         and table_name = v_table ;
      if v_max_endnum < 12 then
         v_max_endnum := 12 ;
      end if ;
      if v_max_endval < 16 then
         v_max_endval := 16 ;
      end if ;
      select count(1)
        into v_ct
            from all_tab_histograms b
       where b.owner = v_owner
             and b.table_name = v_table
             and (exists (select 1 from all_tab_columns
                               where num_buckets > 1
                                 and owner = b.owner
                                 and table_name = b.table_name
                                 and column_name = b.column_name)
                      or
                      exists (select 1 from all_tab_histograms
                               where endpoint_number > 1
                                 and owner = b.owner
                                 and table_name = b.table_name
                                 and column_name = b.column_name)
                     );
    /* Histogram data commented out
      if v_ct > 0 then
              dbms_output.put_line('==========================================================================================');
              dbms_output.put_line('  Histogram Statistics');
              dbms_output.put_line('==========================================================================================');
              dbms_output.put_line(' ' || rpad('Name',v_max_colname) || '  ' ||
                            rpad('Endpoint #',v_max_endnum) || '  ' ||
                            rpad('Endpoint Value',v_max_endval) || '  Endpoint Actual Value');
              v_ct := 0 ;
              for v_rec in hist_stats loop
                  if v_ct = 0 then
                     v_ct := 1 ;
                     prev_col := v_rec.column_name ;
                  elsif prev_col <> v_rec.column_name then
                     dbms_output.put_line('------------------------------------------------------------------------------------------');
                     prev_col := v_rec.column_name ;
                  end if ;
                      dbms_output.put_line(rpad(v_rec.column_name, v_max_colname) || '  ' ||
                            rpad(v_rec.endpoint_number,v_max_endnum) || '  ' ||
                            rpad(v_rec.endpoint_value,v_max_endval) || '  ' ||
                            substr(v_rec.endpoint_actual_value,1,20) ) ;
              end loop ;
      end if ;
    */
      v_ct := 0;
      select count(1)
        into v_ct
        from all_indexes a
       where a.table_owner = v_owner
         and a.table_name = v_table;
      if v_ct > 0 then
              dbms_output.put_line('==========================================================================================');
              dbms_output.put_line('  Index Information');
              dbms_output.put_line('==========================================================================================');
              v_query := 'select a.index_name, substr(a.index_type, 1, 4) index_type,
                                 a.last_analyzed, a.degree, a.partitioned, a.blevel,
                                 a.leaf_blocks, a.distinct_keys,
                                 a.avg_leaf_blocks_per_key, a.avg_data_blocks_per_key,
                                 a.clustering_factor, b.blocks blocks_in_table, b.num_rows rows_in_table
                                            from all_indexes a, all_tables b
                                       where (a.table_name = b.table_name and a.table_owner = b.owner)
                                         and a.table_owner = ''' || UPPER(v_owner) || '''
                                         and a.table_name = ''' || UPPER(v_table) || '''' ;
              print_table (v_query);
              dbms_output.put_line('==========================================================================================');
              dbms_output.put_line('  Index Columns Information');
              dbms_output.put_line('==========================================================================================');
              dbms_output.put_line('Index Name                           Pos# Order Column Name          Expression');
              dbms_output.put_line('==========================================================================================');
      end if;
    end ;
    /
    set verify off feed off numwidth 15 lines 500 heading off
    column column_name format a30 heading 'Column Name'
    column index_name heading 'Index Name' format a30
    column column_position format 999999999 heading 'Position'
    column descend format a5 heading 'Order'
    column column_expression format a40 heading 'Expression'
    break on index_name skip 1
    select b.index_name, b.column_position, b.descend, b.column_name,  e.column_expression
    from all_ind_columns b, all_ind_expressions e
    where b.table_owner = upper('&ownname')
    and b.table_name = UPPER('&tabname')
    and b.index_name = e.index_name(+)
    order by b.index_name, b.column_position, b.column_name
    /
    undefine ownname
    undefine tabname
    set feed on numwidth 12 lines 120
    clear columns
    clear breaks
    set lines 155
    set head on

    脚本table_stats2.sql

      set lines 155
      rem $Header$
      rem $Name$
      rem Copyright (c); 2004 by Hotsos Enterprises, Ltd.
      rem
      rem Retrieve statistics information for a table
      rem
      rem Usage:  SQL>@hstats <table name>
      rem
      --
      -- Modified by Kerry Osborne
      -- commented out Histogram section
      -- added prompts
      -- added ability to run against table in another schmea
      -- added max and min values for column stats using display_raw function
      -- ordered column stats by column name
      -- Modified by Kerry Kong 2016-01-15  此脚本依赖函数DISPLAY_RAW, 执行前请执行脚本display_raw.sql创建此函数,并授权.
      set echo off feed off
      set serveroutput on size 1000000
       accept ownname prompt 'Owner : '
       accept tabname prompt 'Table : '
      set lines 80
      define v_desc = '&ownname..&tabname.'
      desc &v_desc
      set lines 200
      declare
        v_query varchar2(4000)  ;
        v_owner varchar2(30) := upper('&&ownname');
        v_table varchar2(30) := upper('&&tabname');
        v_max_colname   number ;
        v_max_ndv               number ;
        v_max_nulls     number ;
        v_max_bkts      number ;
        v_max_smpl      number ;
        v_max_avg_col_len number ;
        v_max_low       number ;
        v_max_high      number ;
        v_max_endnum    number ;
        v_max_endval    number ;
        v_ct                    number ;
        prev_col                varchar2(30) ;
        cursor col_stats is
        select a.column_name, nvl(a.last_analyzed,to_date('01/01/1900','mm/dd/yyyy')) last_analyzed,
                       decode(a.nullable,'N','NOT NULL','        ') nullable,
                       a.num_distinct, a.density, a.num_nulls,
               a.num_buckets, a.avg_col_len, nvl(to_char(a.sample_size),' ') sample_size,
      display_raw(low_value,data_type) low_value, display_raw(high_value,data_type) high_value
          from all_tab_columns a
         where a.owner = v_owner
           and a.table_name = v_table 
      order by a.column_name;
        cursor hist_stats is
        select b.column_name, b.endpoint_number, b.endpoint_value, b.endpoint_actual_value
              from all_tab_histograms b
         where b.owner = v_owner
               and b.table_name = v_table
               and (exists (select 1 from all_tab_columns
                                 where num_buckets > 1
                                   and owner = b.owner
                                   and table_name = b.table_name
                                   and column_name = b.column_name)
                        or
                        exists (select 1 from all_tab_histograms
                                 where endpoint_number > 1
                                   and owner = b.owner
                                   and table_name = b.table_name
                                   and column_name = b.column_name)
                       )
              order by b.column_name, b.endpoint_number;
              procedure print_table ( p_query in varchar2,  p_date_fmt in varchar2 default 'dd-MON-yyyy hh24:mi:ss' ) is
                          l_theCursor     integer default dbms_sql.open_cursor;
                          l_columnValue   varchar2(4000);
                          l_status        integer;
                          l_descTbl       dbms_sql.desc_tab;
                          l_colCnt        number;
                          l_cs            varchar2(255);
                          l_date_fmt      varchar2(255);
                          -- Small inline procedure to restore the session's state.
                          -- We may have modified the cursor sharing and nls date format
                          -- session variables. This just restores them.
                          procedure restore
                          is
                          begin
                             if ( upper(l_cs) not in ( 'FORCE','SIMILAR' ))
                             then
                                 execute immediate
                                 'alter session set cursor_sharing=exact';
                             end if;
                             if ( p_date_fmt is not null )
                             then
                                 execute immediate
                                     'alter session set nls_date_format=''' || l_date_fmt || '''';
                             end if;
                             dbms_sql.close_cursor(l_theCursor);
                          end restore;
                      begin
                          -- I like to see the dates print out with times, by default. The
                          -- format mask I use includes that.  In order to be "friendly"
                          -- we save the current session's date format and then use
                          -- the one with the date and time.  Passing in NULL will cause
                          -- this routine just to use the current date format.
                          if ( p_date_fmt is not null )
                          then
                             select sys_context( 'userenv', 'nls_date_format' )
                               into l_date_fmt
                               from dual;
                             execute immediate
                             'alter session set nls_date_format=''' || p_date_fmt || '''';
                          end if;
                          -- To be bind variable friendly on ad-hoc queries, we
                          -- look to see if cursor sharing is already set to FORCE or
                          -- similar. If not, set it to force so when we parse literals
                          -- are replaced with binds.
                          if ( dbms_utility.get_parameter_value
                               ( 'cursor_sharing', l_status, l_cs ) = 1 )
                          then
                              if ( upper(l_cs) not in ('FORCE','SIMILAR'))
                              then
                                  execute immediate
                                 'alter session set cursor_sharing=force';
                              end if;
                          end if;
                          -- Parse and describe the query sent to us.  We need
                          -- to know the number of columns and their names.
                          dbms_sql.parse(  l_theCursor,  p_query, dbms_sql.native );
                          dbms_sql.describe_columns
                          ( l_theCursor, l_colCnt, l_descTbl );
                          -- Define all columns to be cast to varchar2s. We
                          -- are just printing them out.
                          for i in 1 .. l_colCnt loop
                              dbms_sql.define_column
                              (l_theCursor, i, l_columnValue, 4000);
                          end loop;
                          -- Execute the query, so we can fetch.
                          l_status := dbms_sql.execute(l_theCursor);
                          -- Loop and print out each column on a separate line.
                          -- Bear in mind that dbms_output prints only 255 characters/line
                          -- so we'll see only the first 200 characters by my design...
                          while ( dbms_sql.fetch_rows(l_theCursor) > 0 )
                          loop
                              for i in 1 .. l_colCnt loop
                                  dbms_sql.column_value
                                  ( l_theCursor, i, l_columnValue );
                                  dbms_output.put_line
                                  ( rpad( l_descTbl(i).col_name, 30 )
                                    || ': ' ||
                                    substr( l_columnValue, 1, 200 ) );
                              end loop;
                              dbms_output.put_line( '-----------------' );
                          end loop;
                          -- Now, restore the session state, no matter what.
                          restore;
                      exception
                          when others then
                              restore;
                              raise;
                      end;
      begin
        dbms_output.put_line('==========================================================================================');
        dbms_output.put_line('  Table Statistics');
        dbms_output.put_line('==========================================================================================');
        v_query := 'select table_name, last_analyzed, trim(degree) degree, partitioned,
                                       num_rows, chain_cnt, blocks, empty_blocks, avg_space,
                                       avg_row_len, monitoring, sample_size
                                  from all_tables
                                 where owner = ''' || UPPER(v_owner) || ''' and table_name = ''' || UPPER(v_table) || '''';
        print_table (v_query);
        v_ct := 0 ;
        select count(1)
          into v_ct
              from all_tab_partitions
         where table_owner = v_owner
           and table_name = v_table;
        if v_ct > 0 then
                dbms_output.put_line('==========================================================================================');
                dbms_output.put_line('  Partition Information');
                dbms_output.put_line('==========================================================================================');
                v_query := 'select partition_name, last_analyzed, high_value,
                                               num_rows, chain_cnt, blocks, empty_blocks,
                                               avg_space, avg_row_len
                                              from all_tab_partitions
                                         where table_owner = ''' || UPPER(v_owner) || '''
                                           and table_name = ''' || UPPER(v_table) || '''';
                print_table (v_query);
        end if ;
        select max(length(column_name)) + 1, max(length(num_distinct)) + 3,
                       max(length(num_nulls)) + 1, max(length(num_buckets)) + 1,
                       max(length(sample_size)) + 1,
                       max(length(avg_col_len)) + 1,
                       max(length(display_raw(low_value,DATA_TYPE))) + 1,
                       max(length(display_raw(high_value,DATA_TYPE))) + 1
          into v_max_colname, v_max_ndv, v_max_nulls, v_max_bkts, v_max_smpl, v_max_avg_col_len, v_max_low, v_max_high
          from all_tab_columns
         where owner = v_owner
           and table_name = v_table ;
        if v_max_nulls < 8 then
           v_max_nulls := 8 ;
        end if ;
        if v_max_bkts < 10 then
           v_max_bkts := 10 ;
        end if ;
        if v_max_smpl < 7 then
           v_max_smpl := 7;
        end if;
        if v_max_avg_col_len < 7 then
           v_max_avg_col_len := 7;
        end if;
        if v_max_low < 4 then
           v_max_low := 4;
        end if;
        if v_max_high < 4 then
           v_max_high := 4;
        end if;
        dbms_output.put_line('===============================================================================================================================');
        dbms_output.put_line('  Column Statistics');
        dbms_output.put_line('===============================================================================================================================');
        dbms_output.put_line('' || rpad('Name',v_max_colname) || '  Analyzed    Null?     ' ||
                      lpad('  NDV',v_max_ndv) || '  ' || lpad('Density',8) || '  ' ||
                      lpad('# Nulls',v_max_nulls) || '  ' || lpad('# Buckets',v_max_bkts) || '  ' ||
                      lpad('Sample',v_max_smpl) || '  ' || lpad('Avg Len',v_max_avg_col_len) || '  ' ||
                      lpad('Min',v_max_low) || '  ' || lpad('Max',v_max_high));
        dbms_output.put_line('===============================================================================================================================');
        for v_rec in col_stats loop
            dbms_output.put_line(rpad(v_rec.column_name,v_max_colname) || '  ' ||
            to_char(v_rec.last_analyzed,'mm/dd/yyyy') || '  ' ||
            v_rec.nullable || '  ' ||
            lpad(v_rec.num_distinct,v_max_ndv) || ' ' ||
            to_char(v_rec.density,'9.999999') || '  ' ||
            lpad(v_rec.num_nulls,v_max_nulls) || '  ' ||
            lpad(v_rec.num_buckets,v_max_bkts) || '  ' ||
            lpad(v_rec.sample_size,v_max_smpl) || '  ' ||
            lpad(v_rec.avg_col_len,v_max_avg_col_len) || '  ' ||
            lpad(v_rec.low_value,v_max_low) || '  ' ||
            lpad(v_rec.high_value,v_max_high));
        end loop ;
        select max(length(column_name)) + 1, max(length(endpoint_number)) + 1,
                       max(length(endpoint_value)) + 1
          into v_max_colname, v_max_endnum, v_max_endval
          from all_tab_histograms
         where owner = v_owner
           and table_name = v_table ;
        if v_max_endnum < 12 then
           v_max_endnum := 12 ;
        end if ;
        if v_max_endval < 16 then
           v_max_endval := 16 ;
        end if ;
        select count(1)
          into v_ct
              from all_tab_histograms b
         where b.owner = v_owner
               and b.table_name = v_table
               and (exists (select 1 from all_tab_columns
                                 where num_buckets > 1
                                   and owner = b.owner
                                   and table_name = b.table_name
                                   and column_name = b.column_name)
                        or
                        exists (select 1 from all_tab_histograms
                                 where endpoint_number > 1
                                   and owner = b.owner
                                   and table_name = b.table_name
                                   and column_name = b.column_name)
                       );
      /* Histogram data commented out
        if v_ct > 0 then
                dbms_output.put_line('==========================================================================================');
                dbms_output.put_line('  Histogram Statistics');
                dbms_output.put_line('==========================================================================================');
                dbms_output.put_line(' ' || rpad('Name',v_max_colname) || '  ' ||
                              rpad('Endpoint #',v_max_endnum) || '  ' ||
                              rpad('Endpoint Value',v_max_endval) || '  Endpoint Actual Value');
                v_ct := 0 ;
                for v_rec in hist_stats loop
                    if v_ct = 0 then
                       v_ct := 1 ;
                       prev_col := v_rec.column_name ;
                    elsif prev_col <> v_rec.column_name then
                       dbms_output.put_line('------------------------------------------------------------------------------------------');
                       prev_col := v_rec.column_name ;
                    end if ;
                        dbms_output.put_line(rpad(v_rec.column_name, v_max_colname) || '  ' ||
                              rpad(v_rec.endpoint_number,v_max_endnum) || '  ' ||
                              rpad(v_rec.endpoint_value,v_max_endval) || '  ' ||
                              substr(v_rec.endpoint_actual_value,1,20) ) ;
                end loop ;
        end if ;
      */
        v_ct := 0;
        select count(1)
          into v_ct
          from all_indexes a
         where a.table_owner = v_owner
           and a.table_name = v_table;
        if v_ct > 0 then
                dbms_output.put_line('===============================================================================================================================');
                dbms_output.put_line('  Index Information');
                dbms_output.put_line('===============================================================================================================================');
                v_query := 'select a.index_name, substr(a.index_type, 1, 4) index_type,
                                   a.last_analyzed, a.degree, a.partitioned, a.blevel,
                                   a.leaf_blocks, a.distinct_keys,
                                   a.avg_leaf_blocks_per_key, a.avg_data_blocks_per_key,
                                   a.clustering_factor, b.blocks blocks_in_table, b.num_rows rows_in_table
                                              from all_indexes a, all_tables b
                                         where (a.table_name = b.table_name and a.table_owner = b.owner)
                                           and a.table_owner = ''' || UPPER(v_owner) || '''
                                           and a.table_name = ''' || UPPER(v_table) || '''' ;
                print_table (v_query);
                dbms_output.put_line('==========================================================================================');
                dbms_output.put_line('  Index Columns Information');
                dbms_output.put_line('==========================================================================================');
                dbms_output.put_line('Index Name                           Pos# Order Column Name          Expression');
                dbms_output.put_line('==========================================================================================');
        end if;
      end ;
      /
      set verify off feed off numwidth 15 lines 500 heading off
      column column_name format a30 heading 'Column Name'
      column index_name heading 'Index Name' format a30
      column column_position format 999999999 heading 'Position'
      column descend format a5 heading 'Order'
      column column_expression format a40 heading 'Expression'
      break on index_name skip 1
      select b.index_name, b.column_position, b.descend, b.column_name,  e.column_expression
      from all_ind_columns b, all_ind_expressions e
      where b.table_owner = upper('&ownname')
      and b.table_name = UPPER('&tabname')
      and b.index_name = e.index_name(+)
      order by b.index_name, b.column_position, b.column_name
      /
      undefine ownname
      undefine tabname
      set feed on numwidth 12 lines 120
      clear columns
      clear breaks
      set lines 155
      set head on

      脚本table_stats2.sql依赖函数display_raw, 如果你想使用table_stats2.sql,必须在数据库创建函数display_raw,并根据实际使用场景进行授权.

        create or replace function display_raw (rawval raw, type varchar2)
        return varchar2
        is
            cn     number;
            cv     varchar2(64);
            cd     date;
            cnv    nvarchar2(64);
            cr     rowid;
            cc     char(64);
            cbf    binary_float;
            cbd    binary_double;
        begin
            if (type = 'VARCHAR2') then
                dbms_stats.convert_raw_value(rawval, cv);
                return to_char(cv);
            elsif (type = 'DATE') then
                dbms_stats.convert_raw_value(rawval, cd);
                return to_char(cd);
            elsif (type = 'NUMBER') then
                dbms_stats.convert_raw_value(rawval, cn);
                return to_char(cn);
            elsif (type = 'BINARY_FLOAT') then
                dbms_stats.convert_raw_value(rawval, cbf);
                return to_char(cbf);
            elsif (type = 'BINARY_DOUBLE') then
                dbms_stats.convert_raw_value(rawval, cbd);
                return to_char(cbd);
            elsif (type = 'NVARCHAR2') then
                dbms_stats.convert_raw_value(rawval, cnv);
                return to_char(cnv);
            elsif (type = 'ROWID') then
                dbms_stats.convert_raw_value(rawval, cr);
                return to_char(cr);
            elsif (type = 'CHAR') then
                dbms_stats.convert_raw_value(rawval, cc);
                return to_char(cc);
            else
                return 'UNKNOWN DATATYPE';
            end if;
        end;
        /
        show errors

        文章转载自DBA闲思杂想录,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论