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