2010-06-01 98 views
3

查詢Oracle 9i上的ALL_TAB_COLS視圖時,它列出標記爲UNUSED的列以及「活動」表列。似乎沒有明確說明列是否爲UNUSED的字段,或者可以加入的任何視圖列出表中未使用的列。如何輕鬆找出哪些是未使用的列,以便我可以將它們從ALL_TAB_COLS中過濾出來?如何判斷ALL_TAB_COLS中哪些列未被使用?

回答

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未使用:

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 
+0

不幸的是,all_tab_cols得到了我需要的一些信息(隱藏的數據類型和LOB列,功能索引的隱藏虛擬列...) – thecoop 2010-06-01 11:49:34

+0

未使用的列名格式保證是相同的(sys_c00002_10060107:25:40 $' )? – thecoop 2010-06-01 11:53:51

+0

對不起,我不知道 - 雖然我是這麼想的。 – 2010-06-01 13:32:47

1

在ALL_TAB_COLUMNS定義的唯一過濾器「其中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列。

+0

不幸的是,還有其他隱藏的列,我需要的信息(索引虛擬列,LOB列...) – thecoop 2010-06-01 14:13:23

相關問題