2014-03-04 101 views
1

我有一个数据库,人们经常从现有的表中创建备份表,我必须在某些时候删除备份表。在oracle中有任何查询来查找具有相同结构但名称不同的所有表。Oracle查找具有相同结构的表名称

+0

使用All_tab_columns表!只是查询它,你会得到一个主意! –

回答

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; 

这应该显示在顶部的原始表。

+0

@OracleUser。 。 。我想通过常用列数排序的列表就足够了。 –

+0

查询不会处理您的atc和atc1别名之间匹配的列的数据类型。此外,您可以将两个别名都加入all_tables,因为all_tab_columns.table_name可以是视图名称,群集名称或表名称。而且,即使只有一列匹配,也会有一个记录返回结果集。 –

+0

@帕特里克。 。 。我错过了“但不同的名字”部分。这显然没有解决这个问题。 –

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 
0

查询下方首先查找所有具有匹配的#列和列位置+名称+数据类型的32位哈希的表。生日悖论在这里发挥作用 - 有一个意外碰撞的外部机会(在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