Oracle查找具有相同结构的表名

时间:2014-03-04 19:35:59

标签: sql oracle database-administration

我有一个数据库,人们经常从现有的表创建备份表,我必须在一段时间之后删除它。在oracle中有任何查询可以查找所有具有相同结构但名称不同的表。

3 个答案:

答案 0 :(得分:0)

如果您有特定的表,请尝试使用此表来获取具有常用列名的表的计数:

select atc.owner, atc.table_name, count(*) as ColumnsInCommon
from all_tab_columns atc join
     all_tab_columns atc1
     on atc.column_name = atc1.column_name and
        atc1.table_name = YOURTABLENAME and
        atc1.owner = YOUROWNER
group by atc.owner, atc.table_name
order by count(*) desc;

这应该显示您的原始表格。

答案 1 :(得分:0)

使用all_tab_columns的别名并将它们连接到all_objects,确保对象类型为TABLE。接下来,确保“匹配”表本身不是(object_id彼此不相等)。

接下来,使用每个表中的总列数来计算匹配的列并进行比较。

        SELECT t1.object_name table_name,
        col_ct.total_cols table_total_cols,
        t2.object_name matching_table,
        COUNT(1) matching_columns_ct
        FROM
        (SELECT o.object_id,
         COUNT(1) total_cols
         FROM all_objects o,
         all_tab_columns tc
         WHERE 1           =1
         AND o.object_type = 'TABLE'
         AND o.owner       = tc.owner
         AND o.object_name = tc.table_name
         GROUP BY o.object_id
         ) col_ct,
        all_objects t1,
        all_objects t2,
        all_tab_columns tc1,
        all_tab_columns tc2
        WHERE 1            =1
        AND t1.object_type = 'TABLE'
        AND t2.object_type = 'TABLE'
        AND t1.owner       =
        &TableOwner
        AND t1.object_name =
        &TableName
        AND t1.object_id    =col_ct.object_id
        AND t1.object_id   != t2.object_id
        AND t1.owner        = tc1.owner
        AND t1.object_name  = tc1.table_name
        AND t2.owner        = tc2.owner
        AND t2.object_name  = tc2.table_name
        AND tc1.column_name = tc2.column_name
        AND tc1.data_type   = tc2.data_type
        GROUP BY t1.object_name,
        col_ct.total_cols,
        t2.object_name
        HAVING COUNT(1) =col_ct.total_cols

答案 2 :(得分:0)

下面的查询首先查找所有匹配#列的列和列位置的32位散列+ name + data_type。生日悖论在这里发挥作用 - 存在意外碰撞的外部机会(在具有65,000个表的数据库中接近50%的可能性为1个误报)。如果您要过滤用户模式并搜索少于65,000个表,请直接查询T0。否则,剩余的SQL将确保您只获得具有匹配列结构的表。

WITH T AS 
  (
    SELECT  OWNER O, 
            TABLE_NAME N, 
            SUM(ORA_HASH(COLUMN_ID||COLUMN_NAME||DATA_TYPE,POWER(2,32)-1)) H, 
            COUNT(*) C
    FROM    DBA_TABLES 
            JOIN  DBA_TAB_COLUMNS USING (OWNER,TABLE_NAME)
    -----------------------------------------------------------------
    -- where clause here to limit schemas to user-defined tables
    -----------------------------------------------------------------
    GROUP BY OWNER, TABLE_NAME
  )
SELECT  O1, N1, O2, N2 
FROM 
        (
            SELECT  T1.N N1, T1.O O1, T2.N N2, T2.O O2, C 
            FROM    T T1 JOIN T T2 USING (H, C)
            WHERE   (T1.N <> T2.N OR T1.O <> T2.O)
        ) T0
---------------------------------------------------------------------
-- Remaining SQL only needed if false-positives must be avoided
---------------------------------------------------------------------
        JOIN DBA_TAB_COLUMNS T1 ON (T0.O1 = T1.OWNER AND T0.N1=T1.TABLE_NAME)
        JOIN DBA_TAB_COLUMNS T2 ON (T0.O2 = T2.OWNER AND T0.N2 = T2.TABLE_NAME
                                    AND T2.COLUMN_ID = T1.COLUMN_ID
                                    AND T2.COLUMN_NAME = T1.COLUMN_NAME
                                    AND T2.DATA_TYPE = T1.DATA_TYPE)
GROUP BY O1, N1, O2, N2, C
HAVING COUNT(*) = C