Suppose we need to compare two database schemas to find out changes such as new tables, columns, and change of data type.
Test
create user USER1 identified by USER1; create user USER2 identified by USER2; create table USER1.T1 (C int); create table USER2.T1 (C int); create table USER1.T2 (C int); create table USER2.T3 (C int); create table USER1.T4 (C int, D int); create table USER2.T4 (C int); create table USER1.T5 (C int, E int); create table USER2.T5 (C int, E varchar(20));
Result
Comparison script
select TABLE_NAME, COLUMN_NAME, DATA_TYPE, OWNER, case when COLUMN_NAME = ' ' then 'Table' else case when DATA_TYPE = ' ' then 'Column' else 'Type' end end DIFF_TYPE from ( ( select C.TABLE_NAME, C.COLUMN_NAME, case when D_COLUMNS.TABLE_NAME is null then C.DATA_TYPE else ' ' end as DATA_TYPE, C.OWNER from DBA_TAB_COLUMNS C inner join ( ( select TABLE_NAME, COLUMN_NAME, DATA_TYPE from DBA_TAB_COLUMNS where OWNER = 'USER1' minus select TABLE_NAME, COLUMN_NAME, DATA_TYPE from DBA_TAB_COLUMNS where OWNER = 'USER2' ) union all ( select TABLE_NAME, COLUMN_NAME, DATA_TYPE from DBA_TAB_COLUMNS where OWNER = 'USER2' minus select TABLE_NAME, COLUMN_NAME, DATA_TYPE from DBA_TAB_COLUMNS where OWNER = 'USER1' ) ) D_TYPE on C.TABLE_NAME = D_TYPE.TABLE_NAME and C.COLUMN_NAME = D_TYPE.COLUMN_NAME and C.DATA_TYPE = D_TYPE.DATA_TYPE left join ( ( select TABLE_NAME, COLUMN_NAME from DBA_TAB_COLUMNS where OWNER = 'USER1' minus select TABLE_NAME, COLUMN_NAME from DBA_TAB_COLUMNS where OWNER = 'USER2' ) union all ( select TABLE_NAME, COLUMN_NAME from DBA_TAB_COLUMNS where OWNER = 'USER2' minus select TABLE_NAME, COLUMN_NAME from DBA_TAB_COLUMNS where OWNER = 'USER1' ) ) D_COLUMNS on C.TABLE_NAME = D_COLUMNS.TABLE_NAME and C.COLUMN_NAME = D_COLUMNS.COLUMN_NAME left join ( ( ( select TABLE_NAME from DBA_TABLES where OWNER = 'USER1' union select VIEW_NAME from DBA_VIEWS where OWNER = 'USER1' ) minus ( select TABLE_NAME from DBA_TABLES where OWNER = 'USER2' union select VIEW_NAME from DBA_VIEWS where OWNER = 'USER2' ) ) union all select VIEW_NAME from DBA_VIEWS where OWNER = 'USER2' union all select VIEW_NAME from DBA_VIEWS where OWNER = 'USER1' ) D_TABLES on C.TABLE_NAME = D_TABLES.TABLE_NAME where C.OWNER in ('USER1', 'USER2') and D_TABLES.TABLE_NAME is NULL ) union all ( select TABLE_NAME, ' ' as COLUMN_NAME, ' ' as DATA_TYPE, OWNER from DBA_TABLES where TABLE_NAME in ( ( select TABLE_NAME from DBA_TABLES where OWNER = 'USER1' minus select TABLE_NAME from DBA_TABLES where OWNER = 'USER2' ) union all ( select TABLE_NAME from DBA_TABLES where OWNER = 'USER2' minus select TABLE_NAME from DBA_TABLES where OWNER = 'USER1' ) ) and OWNER in ('USER1', 'USER2') ) ) order by TABLE_NAME, COLUMN_NAME, DATA_TYPE, OWNER;