2026-03-12 20:23:15
This commit is contained in:
781
vdh/compare_schema.sql
Normal file
781
vdh/compare_schema.sql
Normal file
@@ -0,0 +1,781 @@
|
||||
/*
|
||||
This script compares the object definitions in the current schema
|
||||
to that of a remote schema.
|
||||
The remote schema is defined using a database link.
|
||||
THE SCRIPT COMPARES THE FOLLOWING:
|
||||
- Existence of tables
|
||||
- Existence of columns
|
||||
- Column definitions
|
||||
- Existence of indexes
|
||||
- Index definitions (column usage)
|
||||
- Existence of constraints
|
||||
- Constraint definitions (table, type and reference)
|
||||
- Constraint column usage (for unique, primary key and foreign keys)
|
||||
- Check constraint definitions
|
||||
- Existence of triggers
|
||||
- Definition of triggers
|
||||
- Existence of procedure/packages/functions
|
||||
- Definition of procedures/packages/functions
|
||||
(Ie. the script does not do a complete check, it does not for example
|
||||
check any grants, synonyms, clusters or storage definitions).
|
||||
The script drops and creates a few temporary objects prefixed with
|
||||
the first 3 letter combination (AAA - ZZZ) that does not conflict with any
|
||||
existing objects.
|
||||
If you find ways of improving this script or have any comments and/or
|
||||
problems, please send a mail to the author.
|
||||
This script has been tested on Oracle 7.3.
|
||||
*/
|
||||
undef prex
|
||||
undef prefx
|
||||
undef a
|
||||
undef thisuser
|
||||
undef b
|
||||
undef REMOTESCHEMA
|
||||
undef REMOTEPASSW
|
||||
undef connstring
|
||||
undef c
|
||||
undef todaysdate
|
||||
variable prefx varchar2(3)
|
||||
declare
|
||||
i number ;
|
||||
j number ;
|
||||
k number ;
|
||||
cnt number;
|
||||
begin
|
||||
for i in ascii('A') .. ascii('Z') loop
|
||||
for j in ascii('A') .. ascii('Z') loop
|
||||
for k in ascii('A') .. ascii('Z') loop
|
||||
select count(*) into cnt from user_objects where object_name like
|
||||
chr(i)||chr(j)||chr(k)||'%';
|
||||
if cnt = 0 then
|
||||
:prefx := chr(i)||chr(j)||chr(k);
|
||||
return;
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
column a new_val prex
|
||||
set verify off
|
||||
set linesize 132
|
||||
set feedback off
|
||||
select :prefx a from dual;
|
||||
column b new_val thisuser
|
||||
select user b from dual;
|
||||
column c new_val todaysdate
|
||||
select to_char(sysdate,'DD-MON-YYYY HH24:MI') c from dual;
|
||||
accept REMOTESCHEMA char prompt 'Enter remote username:'
|
||||
accept REMOTEPASSW char prompt 'Enter remote password:' hide
|
||||
accept connstring char prompt 'Enter remote connectstring:'
|
||||
spool dbdiff
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT SCHEMA DEFINITION DIFFERENCES &todaysdate
|
||||
PROMPT
|
||||
PROMPT this schema: &thisuser
|
||||
PROMPT remote schema: &remoteschema.@&connstring
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT
|
||||
PROMPT
|
||||
create database link &prex.lnk connect to &REMOTESCHEMA identified
|
||||
by &REMOTEPASSW using '&CONNSTRING';
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT TABLES MISSING IN THIS SCHEMA:
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
create table &prex.common_tables as
|
||||
select table_name from user_TAbles@&prex.lnk
|
||||
intersect
|
||||
select table_name from user_tables;
|
||||
select table_name from user_TAbles@&prex.lnk
|
||||
minus
|
||||
select table_name from &prex.common_tables;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT TABLES MISSING IN REMOTE SCHEMA:
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name from user_TAbles where table_name not like '&prex.%'
|
||||
minus
|
||||
select table_name from user_tables@&prex.lnk;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT COLUMNS MISSING IN THIS SCHEMA FOR COMMON TABLES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name,column_name from user_tab_columns@&prex.lnk
|
||||
where table_name in
|
||||
(select table_name from &prex.common_tables)
|
||||
minus
|
||||
select table_name,column_name from user_tab_columns
|
||||
where table_name in
|
||||
(select table_name from &prex.common_tables);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT COLUMNS MISSING IN REMOTE SCHEMA FOR COMMON TABLES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name,column_name from user_tab_columns
|
||||
where table_name in
|
||||
(select table_name from &prex.common_tables)
|
||||
minus
|
||||
select table_name,column_name from user_tab_columns@&prex.lnk
|
||||
where table_name in
|
||||
(select table_name from &prex.common_tables);
|
||||
|
||||
create table &prex.diff_cols1
|
||||
( TABLE_NAME VARCHAR2(30),
|
||||
COLUMN_NAME VARCHAR2(30),
|
||||
DATA_TYPE VARCHAR2(9),
|
||||
DATA_LENGTH NUMBER,
|
||||
DATA_PRECISION NUMBER,
|
||||
DATA_SCALE NUMBER,
|
||||
NULLABLE VARCHAR2(1),
|
||||
COLUMN_ID NUMBER,
|
||||
DEFAULT_LENGTH NUMBER,
|
||||
DATA_DEFAULT varchar2(2000));
|
||||
create table &prex.diff_cols2
|
||||
( TABLE_NAME VARCHAR2(30),
|
||||
COLUMN_NAME VARCHAR2(30),
|
||||
DATA_TYPE VARCHAR2(9),
|
||||
DATA_LENGTH NUMBER,
|
||||
DATA_PRECISION NUMBER,
|
||||
DATA_SCALE NUMBER,
|
||||
NULLABLE VARCHAR2(1),
|
||||
COLUMN_ID NUMBER,
|
||||
DEFAULT_LENGTH NUMBER,
|
||||
DATA_DEFAULT varchar2(2000));
|
||||
declare
|
||||
cursor c1 is
|
||||
select
|
||||
l.TABLE_NAME ,
|
||||
l.COLUMN_NAME,
|
||||
l.DATA_TYPE ,
|
||||
l.DATA_LENGTH,
|
||||
l.DATA_PRECISION ,
|
||||
l.DATA_SCALE ,
|
||||
l.NULLABLE,
|
||||
l.COLUMN_ID ,
|
||||
l.DEFAULT_LENGTH ,
|
||||
l.DATA_DEFAULT
|
||||
from user_tab_columns l,&prex.common_tables c
|
||||
where c.table_name=l.table_name ;
|
||||
TYPE rec is record (
|
||||
TABLE_NAME VARCHAR2(30),
|
||||
COLUMN_NAME VARCHAR2(30),
|
||||
DATA_TYPE VARCHAR2(9),
|
||||
DATA_LENGTH NUMBER,
|
||||
DATA_PRECISION NUMBER,
|
||||
DATA_SCALE NUMBER,
|
||||
NULLABLE VARCHAR2(1),
|
||||
COLUMN_ID NUMBER,
|
||||
DEFAULT_LENGTH NUMBER,
|
||||
DATA_DEFAULT varchar2(2000)
|
||||
);
|
||||
c rec;
|
||||
begin
|
||||
open c1;
|
||||
loop
|
||||
fetch c1 into c;
|
||||
exit when c1%NOTFOUND;
|
||||
insert into &prex.diff_cols1 values
|
||||
(c.table_name,c.column_name,c.data_type,c.data_length,
|
||||
c.DATA_PRECISION, c.DATA_SCALE, c.NULLABLE, c.COLUMN_ID,
|
||||
c.DEFAULT_LENGTH, c.DATA_DEFAULT);
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
declare
|
||||
cursor c1 is
|
||||
select
|
||||
l.TABLE_NAME ,
|
||||
l.COLUMN_NAME,
|
||||
l.DATA_TYPE ,
|
||||
l.DATA_LENGTH,
|
||||
l.DATA_PRECISION ,
|
||||
l.DATA_SCALE ,
|
||||
l.NULLABLE,
|
||||
l.COLUMN_ID ,
|
||||
l.DEFAULT_LENGTH ,
|
||||
l.DATA_DEFAULT
|
||||
from user_tab_columns@&prex.lnk l,&prex.common_tables c
|
||||
where c.table_name=l.table_name ;
|
||||
TYPE rec is record (
|
||||
TABLE_NAME VARCHAR2(30),
|
||||
COLUMN_NAME VARCHAR2(30),
|
||||
DATA_TYPE VARCHAR2(9),
|
||||
DATA_LENGTH NUMBER,
|
||||
DATA_PRECISION NUMBER,
|
||||
DATA_SCALE NUMBER,
|
||||
NULLABLE VARCHAR2(1),
|
||||
COLUMN_ID NUMBER,
|
||||
DEFAULT_LENGTH NUMBER,
|
||||
DATA_DEFAULT varchar2(2000)
|
||||
);
|
||||
c rec;
|
||||
begin
|
||||
open c1;
|
||||
loop
|
||||
fetch c1 into c;
|
||||
exit when c1%NOTFOUND;
|
||||
insert into &prex.diff_cols2 values
|
||||
(c.table_name,c.column_name,c.data_type,c.data_length,
|
||||
c.DATA_PRECISION, c.DATA_SCALE, c.NULLABLE, c.COLUMN_ID,
|
||||
c.DEFAULT_LENGTH, c.DATA_DEFAULT);
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
column table_name format a20
|
||||
column column_name format a20
|
||||
column param format a15
|
||||
column local_value format a20
|
||||
column remote_value format a20
|
||||
set arraysize 1
|
||||
set maxdata 32000
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT DIFFERENCE IN COLUMN-DEFS
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select l.table_name,l.column_name,'DATA_DEFAULT' param ,
|
||||
l.DATA_DEFAULT local_value, r.DATA_DEFAULT remote_value
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.DATA_DEFAULT != r.DATA_DEFAULT
|
||||
union
|
||||
select l.table_name,l.column_name,'DATA_TYPE',l.data_type,r.data_type
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.data_type != r.data_type
|
||||
union
|
||||
select l.table_name,l.column_name,'DATA_LENGTH',to_char(l.data_length),
|
||||
to_char(r.data_length)
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.data_length != r.data_length
|
||||
union
|
||||
select l.table_name,l.column_name,'DATA_PRECISION',
|
||||
to_char(l.DATA_PRECISION),to_char(r.DATA_PRECISION)
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.DATA_PRECISION != r.DATA_PRECISION
|
||||
union
|
||||
select l.table_name,l.column_name,'DATA_SCALE',to_char(l.DATA_SCALE),
|
||||
to_char(r.DATA_SCALE)
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.DATA_SCALE != r.DATA_SCALE
|
||||
union
|
||||
select l.table_name,l.column_name,'NULLABLE',l.NULLABLE,r.NULLABLE
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.NULLABLE != r.NULLABLE
|
||||
union
|
||||
select l.table_name,l.column_name,'COLUMN_ID',to_char(l.COLUMN_ID),
|
||||
to_char(r.COLUMN_ID)
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.COLUMN_ID != r.COLUMN_ID
|
||||
union
|
||||
select l.table_name,l.column_name,'DEFAULT_LENGTH',to_char(l.DEFAULT_LENGTH),
|
||||
to_char(r.DEFAULT_LENGTH)
|
||||
from &prex.diff_cols1 l, &prex.diff_cols2 r
|
||||
where l.table_name=r.table_name and
|
||||
l.column_name=r.column_name and l.DEFAULT_LENGTH != r.DEFAULT_LENGTH
|
||||
order by 1,2
|
||||
/
|
||||
|
||||
create table &prex.common_indexes as
|
||||
select table_name, index_name from user_indexes@&prex.lnk
|
||||
where table_name in (select table_name from &prex.common_tables)
|
||||
intersect
|
||||
select table_name, INdex_name from user_indexes
|
||||
where table_name in (select table_name from &prex.common_tables);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT INDEXES MISSING IN THIS SCHEMA FOR COMMON TABLES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name, index_name from user_indexes@&prex.lnk
|
||||
where table_name in (select table_name from &prex.common_tables)
|
||||
minus
|
||||
select table_name, index_name from &prex.common_indexes;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT INDEXES MISSING IN REMOTE SCHEMA FOR COMMON TABLES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name, index_name from user_indexes
|
||||
where table_name in (select table_name from &prex.common_tables)
|
||||
minus
|
||||
select table_name, index_name from &prex.common_indexes;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT COMMON INDEXES WITH DIFFERENT UNIQUENESS
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select a.table_name, a.index_name, a.uniqueness local, b.uniqueness remote
|
||||
from user_indexes a,
|
||||
user_indexes@&prex.lnk b
|
||||
where a.index_name = b.index_name
|
||||
and a.uniqueness != b.uniqueness
|
||||
and (a.table_name, a.index_name) in
|
||||
(select table_name, index_name from &prex.common_indexes);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT INDEX COLUMNS MISSING IN THIS SCHEMA FOR COMMON INDEXES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select index_name, column_name from user_ind_columns@&prex.lnk
|
||||
where (table_name,index_name) in
|
||||
(select table_name,index_name from &prex.common_indexes)
|
||||
minus
|
||||
select index_name, column_name from user_ind_columns
|
||||
where (table_name,index_name) in
|
||||
(select table_name,index_name from &prex.common_indexes);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT INDEX COLUMNS MISSING IN REMOTE SCHEMA FOR COMMON INDEXES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select index_name, column_name from user_ind_columns
|
||||
where (table_name,index_name) in
|
||||
(select table_name,index_name from &prex.common_indexes)
|
||||
minus
|
||||
select index_name, column_name from user_ind_columns@&prex.lnk
|
||||
where (table_name,index_name) in
|
||||
(select table_name,index_name from &prex.common_indexes);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT INDEX COLUMNS POSITIONED DIFFERENTLY FOR COMMON INDEXES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select a.index_name, a.column_name, a.column_position local,
|
||||
b.column_position remote
|
||||
from user_ind_columns a,
|
||||
user_ind_columns@&prex.lnk b
|
||||
where (a.table_name,a.index_name) in
|
||||
(select table_name,index_name from &prex.common_indexes)
|
||||
and b.index_name = a.index_name
|
||||
and b.table_name = a.table_name
|
||||
and a.column_name = b.column_name
|
||||
and a.column_position != b.column_position;
|
||||
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT CONSTRAINTS MISSING IN THIS SCHEMA FOR COMMON TABLES
|
||||
PROMPT (WORKS ONLY FOR CONSTRAINT WITH NON SYSTEM GENERATED NAMES)
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name,constraint_name from user_constraints@&prex.lnk
|
||||
where constraint_name not like 'SYS%' and table_name in
|
||||
(select table_name from &prex.common_tables)
|
||||
minus
|
||||
select table_name,constraint_name from user_constraints
|
||||
where constraint_name not like 'SYS%' and table_name in
|
||||
(select table_name from &prex.common_tables);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT CONSTRAINTS MISSING IN REMOTE SCHEMA FOR COMMON TABLES
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select table_name,constraint_name from user_constraints
|
||||
where constraint_name not like 'SYS%' and table_name in
|
||||
(select table_name from &prex.common_tables)
|
||||
minus
|
||||
select table_name,constraint_name from user_constraints@&prex.lnk
|
||||
where constraint_name not like 'SYS%' and table_name in
|
||||
(select table_name from &prex.common_tables);
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT COMMON CONSTRAINTS, TYPE MISMATCH
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select a.constraint_name,a.constraint_type local_type,
|
||||
b.constraint_type remote_type
|
||||
from user_constraints a, user_constraints@&prex.lnk b where
|
||||
a.table_name = b.table_name and
|
||||
a.constraint_name=b.constraint_name and
|
||||
a.constraint_type !=b.constraint_type;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT COMMON CONSTRAINTS, TABLE MISMATCH
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select a.constraint_name,a.table_name,b.table_name from
|
||||
user_constraints a, user_constraints@&prex.lnk b,
|
||||
(select z.constraint_name from
|
||||
(select constraint_name, table_name from useR_constraints union
|
||||
select constraint_name, table_name from user_constraints@&prex.lnk) z
|
||||
group by constraint_name having count(*) >1) q
|
||||
where a.constraint_name = q.constraint_name and
|
||||
b.constraint_name=q.constraint_name
|
||||
and a.table_name != b.table_name;
|
||||
create table &prex.comcons as
|
||||
select constraint_name, constraint_type, table_name
|
||||
from useR_constraints
|
||||
intersect
|
||||
select constraint_name, constraint_type, table_name
|
||||
from user_constraints@&prex.lnk;
|
||||
delete from &prex.comcons where constraint_name in
|
||||
(select constraint_name from &prex.comcons
|
||||
group by constraint_name having count(*) > 1);
|
||||
delete from &prex.comcons where constraint_name like 'SYS%';
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT DIFFERENCES IN COLUMN USAGE FOR CONSTRAINT DEFS
|
||||
PROMPT (Unique key, Primary Key, Foreign key)
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
declare
|
||||
cursor c1 is
|
||||
select a.constraint_name,a.position,a.column_name,b.constraint_type
|
||||
from user_cons_columns a, &prex.comcons b
|
||||
where a.constraint_name=b.constraint_name
|
||||
union
|
||||
select a.constraint_name,a.position,a.column_name,b.constraint_type
|
||||
from user_cons_columns@&prex.lnk a, &prex.comcons b
|
||||
where a.constraint_name=b.constraint_name
|
||||
minus
|
||||
(select a.constraint_name,a.position,a.column_name,b.constraint_type
|
||||
from user_cons_columns a, &prex.comcons b
|
||||
where a.constraint_name=b.constraint_name
|
||||
intersect
|
||||
select a.constraint_name,a.position,a.column_name,b.constraint_type
|
||||
from user_cons_columns@&prex.lnk a, &prex.comcons b
|
||||
where a.constraint_name=b.constraint_name
|
||||
);
|
||||
i binary_integer;
|
||||
begin
|
||||
for c in c1 loop
|
||||
dbms_output.put_line('COLUMN USAGE DIFFERENCE FOR '||c.constraint_type||
|
||||
' CONSTRAINT '||c.constraint_name);
|
||||
dbms_output.put_line('. Local columns:');
|
||||
i:=1;
|
||||
for c2 in (select column_name col
|
||||
from user_cons_columns
|
||||
where constraint_name=c.constraint_name order by position)
|
||||
loop
|
||||
dbms_output.put_line('. '||c2.col);
|
||||
end loop;
|
||||
i:=1;
|
||||
dbms_output.put_line('. Remote columns:');
|
||||
for c3 in (select column_name col
|
||||
from user_cons_columns@&prex.lnk
|
||||
where constraint_name=c.constraint_name
|
||||
)
|
||||
loop
|
||||
dbms_output.put_line('. '||c3.col);
|
||||
end loop;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT DIFFERENCES IN CHECK CONSTRAINT DEFS
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
set serveroutput on
|
||||
declare
|
||||
cursor c1 is select constraint_name,constraint_type,table_name
|
||||
from &prex.comcons where constraint_type='C';
|
||||
cons varchar2(50);
|
||||
tab1 varchar2(50);
|
||||
tab2 varchar2(50);
|
||||
search1 varchar2(32000);
|
||||
search2 varchar2(32000);
|
||||
begin
|
||||
dbms_output.enable(100000);
|
||||
for c in c1 loop
|
||||
select search_condition into search1 from user_constraints
|
||||
where constraint_name=c.constraint_name;
|
||||
select search_condition into search2 from user_constraints@&prex.lnk
|
||||
where constraint_name=c.constraint_name;
|
||||
if search1 != search2 then
|
||||
dbms_output.put_line('Check constraint '||c.constraint_name||
|
||||
' defined differently!');
|
||||
dbms_output.put_line('. Local definition:');
|
||||
dbms_output.put_line('. '||search1);
|
||||
dbms_output.put_line('. Remote definition:');
|
||||
dbms_output.put_line('. '||search2);
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT TRIGGERS MISSING IN REMOTE SCHEMA
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select trigger_name from user_Triggers minus
|
||||
select trigger_name from user_Triggers@&prex.lnk;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT TRIGGERS MISSING IN THIS SCHEMA
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select trigger_name from user_Triggers minus
|
||||
select trigger_name from user_Triggers@&prex.lnk;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT TRIGGER DEFINITION DIFFERENCES ON COMMON TRIGGERS
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
set serveroutput on
|
||||
declare
|
||||
cursor c1 is select
|
||||
TRIGGER_NAME,TRIGGER_TYPE,TRIGGERING_EVENT,
|
||||
TABLE_NAME,REFERENCING_NAMES,rtrim(WHEN_CLAUSE,' '),STATUS,
|
||||
rtrim(replace(description,'"&thisuser".',null),' ') DESCRIPTION,
|
||||
TRIGGER_BODY from user_Triggers;
|
||||
nam1 varchar2(30);
|
||||
type1 varchar2(16);
|
||||
event1 varchar2(26);
|
||||
table1 varchar2(30);
|
||||
ref1 varchar2(87);
|
||||
when1 varchar2(2000);
|
||||
status1 varchar2(8);
|
||||
desc1 varchar2(2000);
|
||||
body1 varchar2(32000);
|
||||
type2 varchar2(16);
|
||||
event2 varchar2(26);
|
||||
table2 varchar2(30);
|
||||
ref2 varchar2(87);
|
||||
when2 varchar2(2000);
|
||||
status2 varchar2(8);
|
||||
desc2 varchar2(2000);
|
||||
body2 varchar2(32000);
|
||||
pr_head boolean;
|
||||
begin
|
||||
dbms_output.enable(100000);
|
||||
open c1;
|
||||
loop
|
||||
fetch c1 into nam1,type1,event1,table1,ref1,when1,status1,desc1,body1;
|
||||
exit when c1%notfound;
|
||||
begin
|
||||
select
|
||||
TRIGGER_TYPE,TRIGGERING_EVENT,
|
||||
TABLE_NAME,REFERENCING_NAMES,rtrim(WHEN_CLAUSE,' '),STATUS,
|
||||
rtrim(replace(description,upper('"&remoteschema".'),null),' ') DESCRIPTION,
|
||||
TRIGGER_BODY
|
||||
into type2,event2,table2,ref2,when2,status2,desc2,body2
|
||||
from user_Triggers@&prex.lnk
|
||||
where trigger_name=nam1;
|
||||
pr_head := FALSE;
|
||||
if table1 != table2 then
|
||||
dbms_output.put_line('T R I G G E R : '||nam1);
|
||||
dbms_output.put_line('-------------------------------------------------'||
|
||||
'-----------------------');
|
||||
pr_head := TRUE;
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('DEFINED ON DIFFERENT TABLES!');
|
||||
dbms_output.put_line('. This table_name : '||table1);
|
||||
dbms_output.put_line('. Remote table_name: '||table2);
|
||||
end if;
|
||||
if event1 != event2 then
|
||||
if not pr_head then
|
||||
dbms_output.put_line('T R I G G E R : '||nam1);
|
||||
dbms_output.put_line('-------------------------------------------------'||
|
||||
'-----------------------');
|
||||
pr_head := TRUE;
|
||||
end if;
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('DEFINED FOR DIFFERENT EVENTS!');
|
||||
dbms_output.put_line('. This event: '||event1);
|
||||
dbms_output.put_line('. Remote event: '||event2);
|
||||
end if;
|
||||
if type1 != type2 then
|
||||
if not pr_head then
|
||||
dbms_output.put_line('T R I G G E R : '||nam1);
|
||||
dbms_output.put_line('-------------------------------------------------'||
|
||||
'-----------------------');
|
||||
pr_head := TRUE;
|
||||
end if;
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('DIFFERENT TYPES!');
|
||||
dbms_output.put_line('. This type: '||type1);
|
||||
dbms_output.put_line('. Remote: '||type2);
|
||||
end if;
|
||||
if ref1 != ref2 then
|
||||
if not pr_head then
|
||||
dbms_output.put_line('T R I G G E R : '||nam1);
|
||||
dbms_output.put_line('-------------------------------------------------'||
|
||||
'-----------------------');
|
||||
pr_head := TRUE;
|
||||
end if;
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('DIFFERENT REFERENCES!');
|
||||
dbms_output.put_line('. This ref: '||ref1);
|
||||
dbms_output.put_line('. Remote: '||ref2);
|
||||
end if;
|
||||
if when1 != when2 then
|
||||
dbms_output.put_line(' ');
|
||||
if not pr_head then
|
||||
dbms_output.put_line('T R I G G E R : '||nam1);
|
||||
dbms_output.put_line('-------------------------------------------------'||
|
||||
'-----------------------');
|
||||
pr_head := TRUE;
|
||||
end if;
|
||||
dbms_output.put_line('DIFFERENT WHEN CLAUSES!');
|
||||
dbms_output.put_line('. Local when_clause:');
|
||||
dbms_output.put_line(when1);
|
||||
dbms_output.put_line('. Remote when_clause: ');
|
||||
dbms_output.put_line(when2);
|
||||
end if;
|
||||
if status1 != status2 then
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('DIFFERENT STATUS!');
|
||||
dbms_output.put_line('. Local status: '||status1);
|
||||
dbms_output.put_line('. Remote status: '||status2);
|
||||
end if;
|
||||
if replace(desc1,chr(10),'') != replace(desc2,chr(10),'') then
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('DIFFERENT DESCRIPTIONS!');
|
||||
dbms_output.put_line('Local definition: ');
|
||||
dbms_output.put_line(desc1);
|
||||
dbms_output.put_line('Remote definition: ');
|
||||
dbms_output.put_line(desc2);
|
||||
end if;
|
||||
if body1 != body2 then
|
||||
dbms_output.put_line(' ');
|
||||
dbms_output.put_line('THE PL/SQL BLOCKS ARE DIFFERENT! ');
|
||||
dbms_output.put_line(' ');
|
||||
end if;
|
||||
exception when NO_DATA_FOUND then null;
|
||||
when others then raise_application_error(-20010,SQLERRM);
|
||||
end;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT MISSING PROCEDURES/PACKAGES/FUNCTIONS IN REMOTE SCHEMA
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select distinct name,type from user_source minus
|
||||
select distinct name,type from user_source@&prex.lnk;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT MISSING PROCEDURES/PACKAGES/FUNCTIONS IN LOCAL SCHEMA
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select distinct name,type from user_source@&prex.lnk minus
|
||||
select distinct name,type from user_source;
|
||||
create table &prex.comcod as
|
||||
select distinct name,type from user_source intersect
|
||||
select distinct name,type from user_source@&prex.lnk;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT PROCEDURES/PACKAGES/FUNCTIONS WITH DIFFERENT DEFINITIONS
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select distinct q.name Object_name,q.type Object_type from
|
||||
(select a.name,a.type,a.line,a.text
|
||||
from user_source a, &prex.comcod b
|
||||
where a.name=b.name union
|
||||
select a.name,a.type,a.line,a.text
|
||||
from user_source@&prex.lnk a, &prex.comcod b
|
||||
where a.name=b.name
|
||||
minus
|
||||
(select a.name,a.type,a.line,a.text
|
||||
from user_source a, &prex.comcod b
|
||||
where a.name=b.name
|
||||
intersect
|
||||
select a.name,a.type,a.line,a.text
|
||||
from user_source@&prex.lnk a, &prex.comcod b
|
||||
where a.name=b.name )) q;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT VIEWS MISSING IN THIS SCHEMA:
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
create table &prex.common_views as
|
||||
select view_name from user_views@&prex.lnk
|
||||
intersect
|
||||
select view_name from user_views;
|
||||
select view_name from user_views@&prex.lnk
|
||||
minus
|
||||
select view_name from &prex.common_views;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT VIEWS MISSING IN REMOTE SCHEMA:
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
select view_name from user_views
|
||||
minus
|
||||
select view_name from user_views@&prex.lnk;
|
||||
PROMPT
|
||||
PROMPT
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PROMPT VIEWS WITH DIFFERENCES IN THE DEFINITION
|
||||
PROMPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
declare
|
||||
def1 varchar2(32000);
|
||||
def2 varchar2(32000);
|
||||
len1 number;
|
||||
len2 number;
|
||||
i number;
|
||||
cursor c1 is select view_name from &prex.common_views;
|
||||
begin
|
||||
dbms_output.enable(100000);
|
||||
for c in c1 loop
|
||||
select text,text_length into def1,len1
|
||||
from user_Views where view_name=c.view_name;
|
||||
select text,text_length into def2,len2
|
||||
from user_Views@&prex.lnk where view_name=c.view_name;
|
||||
i := 1;
|
||||
def1:=replace(def1,' ','');
|
||||
def2:=replace(def2,' ','');
|
||||
if def1 != def2 or length(def1) != length(def2) then
|
||||
dbms_output.put_line(lpad('-',35+length(c.view_name),'-'));
|
||||
dbms_output.put_line('| '||c.view_name ||
|
||||
' |');
|
||||
dbms_output.put_line(lpad('-',35+length(c.view_name),'-'));
|
||||
dbms_output.put_line('Local text_length: ' || to_char(len1));
|
||||
dbms_output.put_line('Remote text_length): ' || to_char(len2));
|
||||
dbms_output.put_line(' ');
|
||||
i := 1;
|
||||
while i <= length(def1) loop
|
||||
if substr(def1,i,240) != substr(def2,i,240) then
|
||||
dbms_output.put_line('Difference at offset ' || to_char(i)
|
||||
);
|
||||
dbms_output.put_line(' local: ' || substr(def1,i,240));
|
||||
dbms_output.put_line(' remote: ' || substr(def2,i,240));
|
||||
end if;
|
||||
i := i + 240;
|
||||
end loop;
|
||||
end if;
|
||||
if length(def2) > length(def1) then
|
||||
dbms_output.put_line('Remote longer than Local. Next 255 bytes: ');
|
||||
dbms_output.put_line(substr(def2,length(def1),255));
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
drop database link &prex.lnk;
|
||||
drop table &prex.comcod;
|
||||
drop table &prex.diff_cols1;
|
||||
drop table &prex.diff_cols2;
|
||||
drop table &prex.common_tables;
|
||||
drop table &prex.common_views;
|
||||
drop table &prex.ind;
|
||||
drop table &prex.ind1;
|
||||
drop table &prex.ind2;
|
||||
drop table &prex.comcons;
|
||||
spool off
|
||||
set verify on
|
||||
set feedback on
|
||||
undef prex
|
||||
undef prefx
|
||||
undef a
|
||||
undef thisuser
|
||||
undef b
|
||||
undef REMOTESCHEMA
|
||||
undef REMOTEPASSW
|
||||
undef connstring
|
||||
undef c
|
||||
undef todaysdate
|
||||
|
||||
Reference in New Issue
Block a user