Это не будет быстро, и вам будет много чего набирать (если вы не генерируете SQL из user_tab_columns), но вот что я использую, когда мне нужно сравнить две таблицы строка за строкой -по-колонки.
Запрос вернет все строки, которые
- Существует в таблице 1, но отсутствует в таблице 2
- Существует в таблице2, но отсутствует в таблице1
- Существует в обеих таблицах, но имеет хотя бы один столбец с другим значением
(общие идентичные строки будут исключены).
"PK" - это столбец (столбцы), которые составляют ваш первичный ключ.
«a» будет содержать A, если существующая строка существует в table1.
«b» будет содержать B, если текущая строка существует в таблице 2.
select pk
,decode(a.rowid, null, null, 'A') as a
,decode(b.rowid, null, null, 'B') as b
,a.col1, b.col1
,a.col2, b.col2
,a.col3, b.col3
,...
from table1 a
full outer
join table2 b using(pk)
where decode(a.col1, b.col1, 1, 0) = 0
or decode(a.col2, b.col2, 1, 0) = 0
or decode(a.col3, b.col3, 1, 0) = 0
or ...;
Редактировать
Добавлен пример кода, чтобы показать разницу, описанную в комментарии.
Всякий раз, когда одно из значений содержит NULL, результат будет другим.
with a as(
select 0 as col1 from dual union all
select 1 as col1 from dual union all
select null as col1 from dual
)
,b as(
select 1 as col1 from dual union all
select 2 as col1 from dual union all
select null as col1 from dual
)
select a.col1
,b.col1
,decode(a.col1, b.col1, 'Same', 'Different') as approach_1
,case when a.col1 <> b.col1 then 'Different' else 'Same' end as approach_2
from a,b
order
by a.col1
,b.col1;
col1 col1_1 approach_1 approach_2
==== ====== ========== ==========
0 1 Different Different
0 2 Different Different
0 null Different Same <---
1 1 Same Same
1 2 Different Different
1 null Different Same <---
null 1 Different Same <---
null 2 Different Same <---
null null Same Same