如何判断ALL_TAB_COLS中哪些列未使用?

时间:2010-06-01 11:12:48

标签: oracle oracle9i data-dictionary

在Oracle 9i上查询ALL_TAB_COLS视图时,它会列出标记为UNUSED的列以及“活动”表列。似乎没有明确说明列是否为UNUSED的字段,或者我可以加入的任何视图列出表中未使用的列。如何轻松找出未使用的列,以便我可以从ALL_TAB_COLS中过滤掉它们?

2 个答案:

答案 0 :(得分:2)

尝试使用ALL_TAB_COLUMNS而不是ALL_TAB_COLS。在Oracle 11.2中,我发现未使用的列出现在ALL_TAB_COLS中(虽然已重命名)但不在ALL_TAB_COLUMNS中。

我创建了一个这样的表:

create table t1 (c1 varchar2(30), c2 varchar2(30);

然后设置c2 unused:

alter table t1 set unused column c2;

然后我看到了:

select column_name from all_tab_cols where owner='ME' and table_name='T1';

COLUMN_NAME
-----------
C1
SYS_C00002_10060107:25:40$

select column_name from all_tab_columns where owner='ME' and table_name='T1';

COLUMN_NAME
-----------
C1

答案 1 :(得分:1)

ALL_TAB_COLUMNS定义中唯一的过滤器是“where hidden_​​column ='NO'”,因此似乎UNUSED列在HIDDEN_COLUMN字段中被标记。

进一步研究数据定义视图,当列变为UNUSED时,看起来COL $ .PROPERTY设置为32800(位2 ^ 5和2 ^ 15)。 2 ^ 5用于标记隐藏的列,因此似乎2 ^ 15是UNUSED。您可以根据所需的内容创建ALL_TAB_COLS的自定义版本,例如:

CREATE OR REPLACE FORCE VIEW all_tab_cols_rev (owner,
                                               table_name,
                                               column_name,
                                               data_type,
                                               data_type_mod,
                                               data_type_owner,
                                               data_length,
                                               data_precision,
                                               data_scale,
                                               nullable,
                                               column_id,
                                               default_length,
                                               data_default,
                                               num_distinct,
                                               low_value,
                                               high_value,
                                               density,
                                               num_nulls,
                                               num_buckets,
                                               last_analyzed,
                                               sample_size,
                                               character_set_name,
                                               char_col_decl_length,
                                               global_stats,
                                               user_stats,
                                               avg_col_len,
                                               char_length,
                                               char_used,
                                               v80_fmt_image,
                                               data_upgraded,
                                               hidden_column,
                                               virtual_column,
                                               segment_column_id,
                                               internal_column_id,
                                               histogram,
                                               qualified_col_name,
                                               unused_column)
AS
   SELECT u.NAME,
          o.NAME,
          c.NAME,
          DECODE (c.type#,
                  1, DECODE (c.CHARSETFORM, 2, 'NVARCHAR2', 'VARCHAR2'),
                  2, DECODE (c.scale, NULL, DECODE (c.precision#, NULL, 'NUMBER', 'FLOAT'), 'NUMBER'),
                  8, 'LONG',
                  9, DECODE (c.CHARSETFORM, 2, 'NCHAR VARYING', 'VARCHAR'),
                  12, 'DATE',
                  23, 'RAW',
                  24, 'LONG RAW',
                  58, NVL2 (ac.synobj#, (SELECT o.NAME
                                           FROM obj$ o
                                          WHERE o.obj# = ac.synobj#), ot.NAME),
                  69, 'ROWID',
                  96, DECODE (c.CHARSETFORM, 2, 'NCHAR', 'CHAR'),
                  100, 'BINARY_FLOAT',
                  101, 'BINARY_DOUBLE',
                  105, 'MLSLABEL',
                  106, 'MLSLABEL',
                  111, NVL2 (ac.synobj#, (SELECT o.NAME
                                            FROM obj$ o
                                           WHERE o.obj# = ac.synobj#), ot.NAME),
                  112, DECODE (c.CHARSETFORM, 2, 'NCLOB', 'CLOB'),
                  113, 'BLOB',
                  114, 'BFILE',
                  115, 'CFILE',
                  121, NVL2 (ac.synobj#, (SELECT o.NAME
                                            FROM obj$ o
                                           WHERE o.obj# = ac.synobj#), ot.NAME),
                  122, NVL2 (ac.synobj#, (SELECT o.NAME
                                            FROM obj$ o
                                           WHERE o.obj# = ac.synobj#), ot.NAME),
                  123, NVL2 (ac.synobj#, (SELECT o.NAME
                                            FROM obj$ o
                                           WHERE o.obj# = ac.synobj#), ot.NAME),
                  178, 'TIME(' || c.scale || ')',
                  179, 'TIME(' || c.scale || ')' || ' WITH TIME ZONE',
                  180, 'TIMESTAMP(' || c.scale || ')',
                  181, 'TIMESTAMP(' || c.scale || ')' || ' WITH TIME ZONE',
                  231, 'TIMESTAMP(' || c.scale || ')' || ' WITH LOCAL TIME ZONE',
                  182, 'INTERVAL YEAR(' || c.precision# || ') TO MONTH',
                  183, 'INTERVAL DAY(' || c.precision# || ') TO SECOND(' || c.scale || ')',
                  208, 'UROWID',
                  'UNDEFINED'),
          DECODE (c.type#, 111, 'REF'),
          NVL2 (ac.synobj#, (SELECT u.NAME
                               FROM user$ u, obj$ o
                              WHERE o.owner# = u.user#
                                AND o.obj# = ac.synobj#), ut.NAME),
          c.LENGTH,
          c.precision#,
          c.scale,
          DECODE (SIGN (c.null$), -1, 'D', 0, 'Y', 'N'),
          DECODE (c.col#, 0, TO_NUMBER (NULL), c.col#),
          c.deflength,
          c.default$,
          h.distcnt,
          h.lowval,
          h.hival,
          h.density,
          h.null_cnt,
          CASE
             WHEN NVL (h.distcnt, 0) = 0
                THEN h.distcnt
             WHEN h.row_cnt = 0
                THEN 1
             WHEN (   h.bucket_cnt > 255
                   OR (    h.bucket_cnt > h.distcnt
                       AND h.row_cnt = h.distcnt
                       AND h.density * h.bucket_cnt <= 1) )
                THEN h.row_cnt
             ELSE h.bucket_cnt
          END,
          h.timestamp#,
          h.sample_size,
          DECODE (c.CHARSETFORM,
                  1, 'CHAR_CS',
                  2, 'NCHAR_CS',
                  3, NLS_CHARSET_NAME (c.CHARSETID),
                  4, 'ARG:' || c.CHARSETID),
          DECODE (c.CHARSETID, 0, TO_NUMBER (NULL), NLS_CHARSET_DECL_LEN (c.LENGTH, c.CHARSETID) ),
          DECODE (BITAND (h.spare2, 2), 2, 'YES', 'NO'),
          DECODE (BITAND (h.spare2, 1), 1, 'YES', 'NO'),
          h.avgcln,
          c.spare3,
          DECODE (c.type#,
                  1, DECODE (BITAND (c.property, 8388608), 0, 'B', 'C'),
                  96, DECODE (BITAND (c.property, 8388608), 0, 'B', 'C'),
                  NULL),
          DECODE (BITAND (ac.flags, 128), 128, 'YES', 'NO'),
          DECODE (o.status,
                  1, DECODE (BITAND (ac.flags, 256), 256, 'NO', 'YES'),
                  DECODE (BITAND (ac.flags, 2),
                          2, 'NO',
                          DECODE (BITAND (ac.flags, 4), 4, 'NO', DECODE (BITAND (ac.flags, 8), 8, 'NO', 'N/A') ) ) ),
          DECODE (c.property, 0, 'NO', DECODE (BITAND (c.property, 32), 32, 'YES', 'NO') ),
          DECODE (c.property, 0, 'NO', DECODE (BITAND (c.property, 8), 8, 'YES', 'NO') ),
          DECODE (c.segcol#, 0, TO_NUMBER (NULL), c.segcol#),
          c.intcol#,
          CASE
             WHEN NVL (h.row_cnt, 0) = 0
                THEN 'NONE'
             WHEN (   h.bucket_cnt > 255
                   OR (    h.bucket_cnt > h.distcnt
                       AND h.row_cnt = h.distcnt
                       AND h.density * h.bucket_cnt <= 1) )
                THEN 'FREQUENCY'
             ELSE 'HEIGHT BALANCED'
          END,
          DECODE (BITAND (c.property, 1024),
                  1024, (SELECT DECODE (BITAND (cl.property, 1), 1, rc.NAME, cl.NAME)
                           FROM SYS.col$ cl, attrcol$ rc
                          WHERE cl.intcol# = c.intcol# - 1
                            AND cl.obj# = c.obj#
                            AND c.obj# = rc.obj#(+)
                            AND cl.intcol# = rc.intcol#(+)),
                  DECODE (BITAND (c.property, 1), 0, c.NAME, (SELECT tc.NAME
                                                                FROM SYS.attrcol$ tc
                                                               WHERE c.obj# = tc.obj#
                                                                 AND c.intcol# = tc.intcol#) ) ),
          DECODE (c.property, 0, 'NO', DECODE (BITAND (c.property, 32768), 32768, 'YES', 'NO') )
     FROM SYS.col$ c, SYS.obj$ o, SYS.hist_head$ h, SYS.user$ u, SYS.coltype$ ac, SYS.obj$ ot, SYS.user$ ut
    WHERE o.obj# = c.obj#
      AND o.owner# = u.user#
      AND c.obj# = h.obj#(+)
      AND c.intcol# = h.intcol#(+)
      AND c.obj# = ac.obj#(+)
      AND c.intcol# = ac.intcol#(+)
      AND ac.toid = ot.oid$(+)
      AND ot.type#(+) = 13
      AND ot.owner# = ut.user#(+)
      AND (   o.type# IN (3, 4)   /* cluster, view */
           OR (    o.type# = 2   /* tables, excluding iot - overflow and nested tables */
               AND NOT EXISTS (
                         SELECT NULL
                           FROM SYS.tab$ t
                          WHERE t.obj# = o.obj#
                            AND (   BITAND (t.property, 512) = 512
                                 OR BITAND (t.property, 8192) = 8192) ) ) )
      AND (   o.owner# = USERENV ('SCHEMAID')
           OR o.obj# IN (SELECT obj#
                           FROM SYS.objauth$
                          WHERE grantee# IN (SELECT kzsrorol
                                               FROM x$kzsro) )
           OR   /* user has system privileges */
              EXISTS (
                 SELECT NULL
                   FROM v$enabledprivs
                  WHERE priv_number IN
                           (-45 /* LOCK ANY TABLE */,
                            -47 /* SELECT ANY TABLE */,
                            -48 /* INSERT ANY TABLE */,
                            -49 /* UPDATE ANY TABLE */,
                            -50 /* DELETE ANY TABLE */) ) );

我将视图放在一个具有SELECT ANY DICTIONARY特权的单独锁定模式中,然后为它创建一个公共同义词。这样,您的所有用户都只能看到他们有权访问的表的UNUSED_COLUMN列。