Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> Re: Script to compare two schemas

Re: Script to compare two schemas

From: Jared Still <jkstill_at_cybcon.com>
Date: Fri, 25 May 2001 12:57:38 -0700
Message-ID: <F001.0030FE9C.20010525115737@fatcity.com>

On Thursday 24 May 2001 17:20, Helmut Daiminger wrote: > Does anybody out there have a script to compare to database schemas and > list the differences?

I'm forwarding a post I made on this topic a few days ago.

Jared

The database compare script didn't come out to well the first time, so I've just embedded them in this post.

The scripts are:

clears.sql
columns.sql
title.sql
schema_diff.sql

Jared

rem TITLE.SQL   -     This SQL*Plus script builds a standard report
rem                   heading for database reports that are XX columns
rem
column  TODAY           NEW_VALUE       CURRENT_DATE            NOPRINT
column  TIME            NEW_VALUE       CURRENT_TIME            NOPRINT
column  DATABASE        NEW_VALUE       DATA_BASE               NOPRINT
set term off feed off
rem
define COMPANY = "BCBSO"
define HEADING = "&1"
col cPageNumLoc new_value PageNumLoc noprint select ('&&2' - 10 ) cPageNumLoc from dual; rem
TTITLE LEFT "Date: " current_date CENTER company col &&PageNumLoc "Page:" format 999 -
       SQL.PNO SKIP 1 LEFT "Time: " current_time CENTER heading RIGHT -
       format a15 SQL.USER SKIP 1 CENTER format a20 data_base SKIP 2
rem
rem
set heading off
set pagesize 0
rem
column passout new_value dbname noprint
SELECT TO_CHAR(SYSDATE,'MM/DD/YY') TODAY,
       TO_CHAR(SYSDATE,'HH:MI AM') TIME,
       --DATABASE||' Database' DATABASE,
       --rtrim(database) passout
       name||' Database' DATABASE,
       lower(rtrim(name)) passout

FROM v$database;
set term on feed on
rem
set heading on
set pagesize 58
set line &&2
set newpage 0
define db = '_&dbname'
undef 1 2

col blocks format 99,999,999 head 'BLOCKS'

col db_link format a30 head 'DB LINK'
col db_link_instance format a30 head 'DB LINK|INSTANCE'
col db_link_username format a10 head 'DB LINK|USERNAME'
col empty_blocks format 99,999,999 head 'EMPTY BLOCKS' col host format a10 head 'HOST'
col index_name format a30 head 'INDEX NAME' col initial_extent format 9,999,999,999 head 'INITIAL|EXTENT' col instance format a4 head 'INST'
col max_blocks format 9,999,999 head 'MAX BLOCKS'
col max_bytes format 99,999,999,999 head 'MAX BYTES'
col max_extents format 999,999 head 'MAX|EXTENTS'
col min_extents format 999 head 'MIN|EXT'
col next_extent format 9,999,999,999 head 'NEXT|EXTENT' col object_name format a30 head 'OBJECT NAME' col owner format a10 head 'OWNER'
col pct_free format 999 head 'PCT|FREE'
col pct_increase format 999 head 'PCT|INC'
col pct_used format 999 head 'PCT|USED'

col synonym_name format a30 head 'SYNONYM NAME' col table_name format a30 head 'TABLE NAME' col table_owner format a10 head 'TABLE|OWNER' col tablespace_name format a15 head 'TABLESPACE|NAME' col timestamp format a19 head 'TIME STAMP' col username format a10 head 'USERNAME'
col last_ddl_time head 'LAST DDL|TIME'
col created head 'CREATED'
col procedure_name format a30 head 'PROCEDURE NAME' col function_name format a30 head 'FUNCTION NAME'
col package_name format a30 head 'PACKAGE NAME'
col package_body_name format a30 head 'PACKAGE BODY NAME'
col segment_name format a30 head 'SEGMENT NAME'

----------------------

clear col
clear break
clear computes

btitle ''
ttitle ''

btitle off
ttitle off


@clears
@columns

col cuser_1 noprint new_value uuser_1
col cuser_2 noprint new_value uuser_2
col cinstance_1 noprint new_value uinstance_1 col cinstance_2 noprint new_value uinstance_2

prompt
prompt
prompt schema_diff will report differences in tables prompt between any 2 users on any 2 databases prompt

set term on feed on
prompt User 1:
set term off feed off
select upper('&1') cuser_1 from dual;

set term on feed on
prompt instance 1:
set term off feed off
select upper('&2') cinstance_1 from dual;

set term on feed on
prompt User 2:
set term off feed off
select upper('&3') cuser_2 from dual;

set term on feed on
prompt instance 2:
set term off feed off
select upper('&4') cinstance_2 from dual;

set term on feed on

drop table table_diff;

create table table_diff as
select table_name, column_name, data_type, data_length, data_precision, data_scale
from all_tab_columns@&&uinstance_1
where 1=2
/

alter table table_diff add( instance varchar2(8) );

create index table_diff_idx on table_diff ( table_name, column_name, instance );

insert into table_diff ( table_name, column_name, data_type, data_length, data_precision, data_scale )

        select table_name, column_name, data_type, data_length, data_precision, data_scale

        from all_tab_columns@&&uinstance_1
        where owner = '&&uuser_1'
        minus
        select table_name, column_name, data_type, data_length, data_precision,
data_scale
        from all_tab_columns@&&uinstance_2
        where owner = '&&uuser_2'

/

update table_diff set instance = '&&uinstance_1';

insert into table_diff ( table_name, column_name, data_type, data_length, data_precision, data_scale )

        select table_name, column_name, data_type, data_length, data_precision, data_scale

        from all_tab_columns@&&uinstance_2
        where owner = '&&uuser_2'
        minus
        select table_name, column_name, data_type, data_length, data_precision,
data_scale
        from all_tab_columns@&&uinstance_1
        where owner = '&&uuser_1'

/

update table_diff set instance = '&&uinstance_2' where instance is null;

commit;

drop table index_diff;

create table index_diff as
select index_name, table_name, column_name, column_position, column_length from all_ind_columns@&&uinstance_1
where 1=2
/

alter table index_diff add( instance varchar2(8) );

create index index_diff_idx on index_diff (

        table_name,
        column_name, column_position, column_length
)
/

insert into index_diff ( index_name, table_name, column_name, column_position, column_length )

        select index_name,  table_name, column_name, column_position, column_length
        from all_ind_columns@&&uinstance_1
        where index_owner = '&&uuser_1'
        minus
        select index_name, table_name, column_name, column_position, column_length
        from all_ind_columns@&&uinstance_2
        where index_owner = '&&uuser_2'

/

update index_diff set instance = '&&uinstance_1';

insert into index_diff ( index_name, table_name, column_name, column_position, column_length )

        select index_name, table_name, column_name, column_position, column_length
        from all_ind_columns@&&uinstance_2
        where index_owner = '&&uuser_2'
        minus
        select index_name, table_name, column_name, column_position, column_length
        from all_ind_columns@&&uinstance_1
        where index_owner = '&&uuser_1'

/

update index_diff set instance = '&&uinstance_2' where instance is null;

commit;

drop table arg_diff;

create table arg_diff as
SELECT

        obj# obj#
        ,procedure$ procedure
        ,argument argument
        ,type type

   ,overload# overload
   ,position position

        ,sequence# sequence

   ,default# "DEFAULT"
   ,in_out in_out
   ,level# "LEVEL"
        ,length length
   ,precision "PRECISION"

   ,scale scale
   ,radix radix
FROM sys.ARGUMENT$@&uinstance_1
where 1 = 2
/

alter table arg_diff add( instance varchar2(8), object_name varchar2(30), object_type varchar2(13) );
alter table arg_diff modify( obj# null );

create index arg_diff_idx on arg_diff ( obj#, argument, type );

insert into arg_diff

        (
                 object_name, object_type, procedure, argument, type, overload, 
position,
sequence,
                "DEFAULT", in_out, "LEVEL", length, "PRECISION", scale, radix
        )
        select
                obj.object_name ,obj.object_type ,arg.procedure$ ,arg.argument
                ,arg.type ,arg.overload# ,arg.position ,arg.sequence# ,arg.default#
,arg.in_out
        ,arg.level# ,arg.length ,arg.precision ,arg.scale ,arg.radix
        from sys.argument$@&&uinstance_1 arg, dba_objects@&&uinstance_1 obj
        where arg.obj# = obj.object_id
        and obj.owner = '&&uuser_1'
        minus
        select
                obj.object_name ,obj.object_type ,arg.procedure$ ,arg.argument
                ,arg.type ,arg.overload# ,arg.position ,arg.sequence# ,arg.default#
,arg.in_out
        ,arg.level# ,arg.length ,arg.precision ,arg.scale ,arg.radix
        from sys.argument$@&&uinstance_2 arg, dba_objects@&&uinstance_2 obj
        where arg.obj# = obj.object_id
        and obj.owner = '&&uuser_2'

/

update arg_diff
set instance = '&&uinstance_1'
/

drop table remote_dba_objects;
drop table remote_arguments;

create table remote_dba_objects
as
select *
from dba_objects@&&uinstance_1
/

create index remote_dba_object_idx1
on remote_dba_objects( object_type, object_id ) /

create index remote_dba_object_idx2
on remote_dba_objects( object_id )
/

create table remote_arguments
as
select

        obj#, procedure$,overload#,position,sequence#,level#,
        argument,type,default#,in_out,length,precision,scale,
        radix,deflength

from sys.argument$@&&uinstance_1
/

create index remote_arguments_idx1
on remote_arguments( argument, type )
/

update arg_diff diff
set obj# = (

        select obj#
        from remote_arguments arg, remote_dba_objects obj
        where arg.obj# = obj.object_id
        and obj.object_name = diff.object_name
        and obj.object_type = diff.object_type
        and obj.owner = '&&uuser_1'
        and nvl(arg.procedure$, 'NONE') = nvl(diff.procedure, 'NONE')
        and arg.argument = diff.argument
        and arg.type = diff.type
        and arg.overload# = diff.overload
        and diff.instance = '&&uinstance_1'
)
where instance = '&&uinstance_1'
/

insert into arg_diff

        (
                object_name, object_type, procedure, argument, type, overload, 
position,
sequence,
                "DEFAULT", in_out, "LEVEL", length, "PRECISION", scale, radix
        )
        select
                obj.object_name ,obj.object_type ,arg.procedure$ ,arg.argument
                ,arg.type ,arg.overload# ,arg.position ,arg.sequence# ,arg.default#
,arg.in_out
        ,arg.level# ,arg.length ,arg.precision ,arg.scale ,arg.radix
        from sys.argument$@&&uinstance_2 arg, dba_objects@&&uinstance_2 obj
        where arg.obj# = obj.object_id
        and obj.owner = '&&uuser_2'
        minus
        select
                obj.object_name ,obj.object_type ,arg.procedure$ ,arg.argument
                ,arg.type ,arg.overload# ,arg.position ,arg.sequence# ,arg.default#
,arg.in_out
        ,arg.level# ,arg.length ,arg.precision ,arg.scale ,arg.radix
        from sys.argument$@&&uinstance_1 arg, dba_objects@&&uinstance_1 obj
        where arg.obj# = obj.object_id
        and obj.owner = '&&uuser_1'

/

update arg_diff
set instance = '&&uinstance_2'
where instance is null
/

drop table remote_dba_objects;
drop table remote_arguments;

create table remote_dba_objects
as
select *
from dba_objects@&&uinstance_2
/

create index remote_dba_object_idx1
on remote_dba_objects( object_type, object_id ) /

create index remote_dba_object_idx2
on remote_dba_objects( object_id )
/

create table remote_arguments
as
select

        obj#, procedure$,overload#,position,sequence#,level#,
        argument,type,default#,in_out,length,precision,scale,
        radix,deflength

from sys.argument$@&&uinstance_2
/

create index remote_arguments_idx1
on remote_arguments( argument, type )
/

update arg_diff diff
set obj# = (

        select obj#
        from remote_arguments arg, remote_dba_objects obj
        where arg.obj# = obj.object_id
        and obj.object_name = diff.object_name
        and obj.object_type = diff.object_type
        and obj.owner = '&&uuser_2'
        and nvl(arg.procedure$, 'NONE') = nvl(diff.procedure, 'NONE')
        and arg.argument = diff.argument
        and arg.type = diff.type
        and arg.overload# = diff.overload
        and diff.instance = '&&uinstance_2'
)
where instance = '&&uinstance_2'
/

drop table remote_dba_objects;
drop table remote_arguments;


break on table_name on column_name on username

col data_precision format 999999 head 'PREC'
col data_scale format 999999 head 'SCALE'
col data_length format 999999 head 'LENGTH'
col column_name format a30 head 'COLUMN NAME'

set trimspool on

spool table_diff.txt

@title 'Table Diffs User1: &&uuser_1@&&uinstance_1 User2: &&uuser_2@&&uinstance_2' 120

select

        t1.table_name,
        t1.column_name,
        '&&uuser_1' username,
        instance,
        t1.data_type,
        t1.data_precision,
        t1.data_scale,
        t1.data_length

from all_tab_columns@&&uinstance_1 t1, table_diff d1 where owner = '&&uuser_1'
and t1.table_name  = d1.table_name
and t1.column_name = d1.column_name
and d1.instance = '&&uinstance_1'

union all
select
        t2.table_name,
        t2.column_name,
        '&&uuser_2' username,
        instance,
        t2.data_type,
        t2.data_length,
        t2.data_scale,
        t2.data_precision

from all_tab_columns@&&uinstance_2 t2, table_diff d2 where owner = '&&uuser_2'
and t2.table_name  = d2.table_name
and t2.column_name = d2.column_name
and d2.instance = '&&uinstance_2'

order by 1,2,3,4
/

break on index_name on table_name

col data_precision format 999999 head 'PREC'
col data_scale format 999999 head 'SCALE'
col data_length format 999999 head 'LENGTH'
col column_name format a30 head 'COLUMN NAME'

col column_position format 999 head 'COL|POS' col column_length format 99999 head 'COL|LEN'

@title 'Index Diffs User1: &&uuser_1@&&uinstance_1 User2: &&uuser_2@&&uinstance_2' 135

col username format a10 head 'INDEX|OWNER'

spool index_diff.txt

select

        t1.index_name,
        '&&uuser_1' username,
        instance,
        t1.table_name,
        t1.column_name,
        t1.column_position,
        t1.column_length

from all_ind_columns@&&uinstance_1 t1, index_diff d1 where index_owner = '&&uuser_1'
and t1.table_name  = d1.table_name
and t1.column_name = d1.column_name
and t1.column_position = d1.column_position
and t1.column_length = d1.column_length
and d1.instance = '&&uinstance_1'

union all
select
        t2.index_name,
        '&&uuser_2' username,
        instance,
        t2.table_name,
        t2.column_name,
        t2.column_position,
        t2.column_length

from all_ind_columns@&&uinstance_2 t2, index_diff d2 where index_owner = '&&uuser_2'
and t2.table_name  = d2.table_name
and t2.column_name = d2.column_name
and t2.column_position = d2.column_position
and t2.column_length = d2.column_length
and d2.instance = '&&uinstance_2'

order by 1,2,3,4,5,6
/

col procedure format a40 head 'PROCEDURE'

break on procedure on overload

@title 'Argument Diffs User1: &&uuser_1@&&uinstance_1 User2: &&uuser_2@&&uinstance_2' 200

spool arg_diff.txt

SELECT

        substr(
                obj.OBJECT_NAME||
                decode( arg.procedure$,null,'','.') ||
                arg.procedure$,1,60
        ) procedure
   ,arg.OVERLOAD# overload
        ,arg.ARGUMENT
        ,diff.instance
        ,obj.object_type
        ,decode(arg.type,
                1, 'VARCHAR2',
                2, 'NUMBER',
                8, 'LONG',
                9, 'VARCHAR',
                12, 'DATE',
                23, 'RAW',
                24, 'LONG RAW',
                69, 'ROWID',
                96, 'CHAR',
                250, 'RECORD',
                252, 'BOOLEAN',
                -- just show type# as default
                substr(to_char(arg.type),1,10)
        ) type

   ,arg.POSITION
   ,NVL(arg.DEFAULT#,0) DEFAULT#

        ,decode(arg.IN_OUT,null,'IN', 2,'IN_OUT', 'UNKNOWN' ) IN_OUT    ,NVL(arg.LEVEL#,0) LEVEL#

        ,NVL(arg.LENGTH,0) LENGTH

   ,NVL(arg.PRECISION,0) PRECISION
   ,NVL(arg.SCALE,0) SCALE
   ,NVL(arg.RADIX,0) RADIX
from
        sys.argument$@&&uinstance_1 arg
        ,dba_objects@&&uinstance_1 obj
        ,arg_diff diff

where arg.obj# = obj.object_id
and obj.owner = '&&uuser_1'
and diff.obj# = arg.obj#
and nvl(diff.procedure,'NONE') = nvl(arg.procedure$,'NONE')
and diff.argument = arg.argument
and diff.type = arg.type
and diff.overload = arg.overload#
and diff.instance = '&&uinstance_1'

union all
SELECT
        substr(
                obj.OBJECT_NAME||
                decode( arg.procedure$,null,'','.') ||
                arg.procedure$,1,60
        ) procedure
   ,arg.OVERLOAD# overload
        ,arg.ARGUMENT
        ,diff.instance
        ,obj.object_type
        ,decode(arg.type,
                1, 'VARCHAR2',
                2, 'NUMBER',
                8, 'LONG',
                9, 'VARCHAR',
                12, 'DATE',
                23, 'RAW',
                24, 'LONG RAW',
                69, 'ROWID',
                96, 'CHAR',
                250, 'RECORD',
                252, 'BOOLEAN',
                -- just show type# as default
                substr(to_char(arg.type),1,10)
        ) type

   ,arg.POSITION
   ,NVL(arg.DEFAULT#,0) DEFAULT#

        ,decode(arg.IN_OUT,null,'IN', 2,'IN_OUT', 'UNKNOWN' ) IN_OUT    ,NVL(arg.LEVEL#,0) LEVEL#

        ,NVL(arg.LENGTH,0) LENGTH

   ,NVL(arg.PRECISION,0) PRECISION
   ,NVL(arg.SCALE,0) SCALE
   ,NVL(arg.RADIX,0) RADIX
from
        sys.argument$@&&uinstance_2 arg
        ,dba_objects@&&uinstance_2 obj
        ,arg_diff diff

where arg.obj# = obj.object_id
and obj.owner = '&&uuser_2'
and diff.obj# = arg.obj#
and nvl(diff.procedure,'NONE') = nvl(arg.procedure$,'NONE')
and diff.argument = arg.argument
and diff.type = arg.type
and diff.overload = arg.overload#
and diff.instance = '&&uinstance_2'

order by 1,2,3,4,5
/

@title 'Sequence Diffs User1: &&uuser_1@&&uinstance_1 User2: &&uuser_2@&&uinstance_2' 110

col sequence_name format a30 head 'SEQUENCE NAME' col last_number format 999999999999 head 'LAST|NUMBER' col min_value format 9999999999 head 'MIN|VALUE' col max_value format 999999999999 head 'MAX|VALUE' col increment_by format 999999 head 'INCREMENT'

col cache_size format 999999 head 'CACHE|SIZE'
col cycle_flag format a5 head 'CYCLE|FLAG'
col order_flag format a5 head 'ORDER|FLAG'

break on sequence_name skip 1

spool sequence_diff.txt

(

        (
                select
                        sequence_name, '&&uinstance_1' instance ,last_number, 
min_value,max_value,
                        increment_by,cycle_flag,order_flag,
                        cache_size
                from dba_sequences@&&uinstance_1
                where sequence_owner = '&&uuser_1'
        )
        minus
        (
                select
                        sequence_name, '&&uinstance_2' instance ,last_number, 
min_value,max_value,
                        increment_by,cycle_flag,order_flag,
                        cache_size
                from dba_sequences@&&uinstance_2
                where sequence_owner = '&&uuser_2'
        )

)
union
(
        (
                select
                        sequence_name, '&&uinstance_2' instance ,last_number, 
min_value,max_value,
                        increment_by,cycle_flag,order_flag,
                        cache_size
                from dba_sequences@&&uinstance_2
                where sequence_owner = '&&uuser_2'
        )
        minus
        (
                select
                        sequence_name, '&&uinstance_1' instance ,last_number, 
min_value,max_value,
                        increment_by,cycle_flag,order_flag,
                        cache_size
                from dba_sequences@&&uinstance_1
                where sequence_owner = '&&uuser_1'
        )

)
/

spool off

undef 1 2 3 4

prompt
prompt
prompt
prompt Your reports in the following files: prompt
prompt table_diff.txt
prompt index_diff.txt
prompt arg_diff.txt
prompt sequence_diff.txt
prompt


--

Please see the official ORACLE-L FAQ: http://www.orafaq.com
--

Author: Jared Still
  INET: jkstill_at_cybcon.com

Fat City Network Services    -- (858) 538-5051  FAX: (858) 538-5051
San Diego, California        -- Public Internet access / Mailing Lists
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in the message BODY, include a line containing: UNSUB ORACLE-L (or the name of mailing list you want to be removed from). You may also send the HELP command for other information (like subscribing). Received on Fri May 25 2001 - 14:57:38 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US