Showing posts with label Schema Compare. Show all posts
Showing posts with label Schema Compare. Show all posts

Monday, June 16, 2014

Data comparison

When we  want to synchronize the data between same or multiple databases , oracle 11g provides new package called DBMS_COMPARISON.  This is a procedural logic. 


If this is a straightforward operation , please use MERGE statement.


Let us look at an example.


1. Let us create an user in the source database and create a table called emp from scott schema.


SQL> grant connect , dba to testuser identified by tesTusr ;
Grant succeeded.


SQL> create table emp as select * from scott.emp;
Table created.



SQL> alter table emp add constraint emp_pk primary key(empno);
Table altered.



In the destinaton database , let me create an user called  testuser.
And also create a database link to the source database.



SQL> grant connect , dba to testuser identified by tesTusr ;
Grant succeeded.


C:\Users\mohideen>sqlplus testuser/tesTusr

SQL*Plus: Release 11.2.0.1.0 Production on Sun Aug 22 17:14:31 2010
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options

SQL> create database link
  2  remotedb_link connect to srcuser
  3      identified by srcusr
  4      using 'remotedb';

Database link created.
SQL> select * from dual@remotedb_link;

D
-
X

SQL> create table emp as select * from srcuser.emp@remotedb_link where 1= 2;

Table created.

OK... We are all set . Let us sync it... 



SQL> DECLARE
  2    scan_info  dbms_comparison.comparison_type;
  3    scan_id    INTEGER;
  4    consistent BOOLEAN;
  5  BEGIN
  6
  7    --  dbms_comparison.drop_comparison(comparison_name => 'comp_emp');
  8    dbms_comparison.create_comparison(comparison_name    => 'comp_emp',
  9                                      schema_name        => 'testuser',
 10                                      object_name        => 'emp',
 11                                      dblink_name        => 'remotedb_link',
 12                                      remote_schema_name => 'srcuser',
 13                                      remote_object_name => 'emp');
 14
 15    consistent := dbms_comparison.compare(comparison_name => 'comp_emp',
 16                                          scan_info       => scan_info);
 17
 18    IF consistent = TRUE THEN
 19      dbms_output.put_line('No differences were found.');
 20    ELSE
 21      dbms_output.put_line('Differences were found.');
 22    END IF;
 23
 24    dbms_comparison.converge(comparison_name  => 'comp_emp',
 25                             scan_id          => scan_info.scan_id,
 26                             scan_info        => scan_info,
 27                             converge_options => dbms_comparison.CMP_CONVERGE_REMOTE_WINS);
 28
 29    dbms_output.put_line('Scan ID: ' || scan_info.scan_id);
 30    dbms_output.put_line('Local Rows Merged:' || scan_info.loc_rows_merged);
 31    dbms_output.put_line('Remote Rows Merged:' || scan_info.rmt_rows_merged);
 32    dbms_output.put_line('Local Rows Deleted:' || scan_info.loc_rows_deleted);
 33    dbms_output.put_line('Remote Rows Deleted:' ||
 34                         scan_info.rmt_rows_deleted);
 35  END;
 36  /
DECLARE
*
ERROR at line 1:
ORA-23626: No eligible index on table TESTUSER.EMP
ORA-06512: at "SYS.DBMS_COMPARISON", line 4793
ORA-06512: at "SYS.DBMS_COMPARISON", line 448
ORA-06512: at line 8


OOPS ... We need to add an index . Oracle compares the data by index . ie , The data between the source and the destination objects should be uniquely identifiable.



SQL> alter table emp add constraint emp_pk primary key(empno);
Table altered.

SQL> DECLARE
  2    scan_info  dbms_comparison.comparison_type;
  3    scan_id    INTEGER;
  4    consistent BOOLEAN;
  5  BEGIN
  6
  7    --  dbms_comparison.drop_comparison(comparison_name => 'comp_emp');
  8    dbms_comparison.create_comparison(comparison_name    => 'comp_emp',
  9                                      schema_name        => 'testuser',
 10                                      object_name        => 'emp',
 11                                      dblink_name        => 'remotedb_link',
 12                                      remote_schema_name => 'srcuser',
 13                                      remote_object_name => 'emp');
 14
 15    consistent := dbms_comparison.compare(comparison_name => 'comp_emp',
 16                                          scan_info       => scan_info);
 17
 18    IF consistent = TRUE THEN
 19      dbms_output.put_line('No differences were found.');
 20    ELSE
 21      dbms_output.put_line('Differences were found.');
 22    END IF;
 23
 24    dbms_comparison.converge(comparison_name  => 'comp_emp',
 25                             scan_id          => scan_info.scan_id,
 26                             scan_info        => scan_info,
 27                             converge_options => dbms_comparison.CMP_CONVERGE_REMOTE_WINS);
 28
 29    dbms_output.put_line('Scan ID: ' || scan_info.scan_id);
 30    dbms_output.put_line('Local Rows Merged:' || scan_info.loc_rows_merged);
 31    dbms_output.put_line('Remote Rows Merged:' || scan_info.rmt_rows_merged);
 32    dbms_output.put_line('Local Rows Deleted:' || scan_info.loc_rows_deleted);
 33    dbms_output.put_line('Remote Rows Deleted:' ||
 34                         scan_info.rmt_rows_deleted);
 35  END;
 36  /
Differences were found.
Scan ID: 1
Local Rows Merged:14
Remote Rows Merged:0
Local Rows Deleted:0
Remote Rows Deleted:0

PL/SQL procedure successfully completed.


Yes . We did it . The data has been synchronized.  Oracle found there was a difference between the source and the destination objects . Since , we said synchorize the data if there were differences , it did it .

As you can see in the previous example , 

1. first ,  we have to create an comparison object ( line 8 ) 
2. second ,  we have to compare the objects ( line 15) 
3. Based on the output of step 2, we sync ( converge)  the data .. We can either say which site wins ( either REMOTE or LOCAL) .


SQL> select count(*) from emp;
  COUNT(*)
----------
        14



SQL> DECLARE
  2    scan_info  dbms_comparison.comparison_type;
  3    scan_id    INTEGER;
  4    consistent BOOLEAN;
  5  BEGIN
  6
  7    --  dbms_comparison.drop_comparison(comparison_name => 'comp_emp');
  8    dbms_comparison.create_comparison(comparison_name    => 'comp_emp',
  9                                      schema_name        => 'testuser',
 10                                      object_name        => 'emp',
 11                                      dblink_name        => 'remotedb_link',
 12                                      remote_schema_name => 'srcuser',
 13                                      remote_object_name => 'emp');
 14
 15    consistent := dbms_comparison.compare(comparison_name => 'comp_emp',
 16                                          scan_info       => scan_info);
 17
 18    IF consistent = TRUE THEN
 19      dbms_output.put_line('No differences were found.');
 20    ELSE
 21      dbms_output.put_line('Differences were found.');
 22    END IF;
 23
 24    dbms_comparison.converge(comparison_name  => 'comp_emp',
 25                             scan_id          => scan_info.scan_id,
 26                             scan_info        => scan_info,
 27                             converge_options => dbms_comparison.CMP_CONVERGE_REMOTE_WINS);
 28
 29    dbms_output.put_line('Scan ID: ' || scan_info.scan_id);
 30    dbms_output.put_line('Local Rows Merged:' || scan_info.loc_rows_merged);
 31    dbms_output.put_line('Remote Rows Merged:' || scan_info.rmt_rows_merged);
 32    dbms_output.put_line('Local Rows Deleted:' || scan_info.loc_rows_deleted);
 33    dbms_output.put_line('Remote Rows Deleted:' ||
 34                         scan_info.rmt_rows_deleted);
 35  END;
 36  /
DECLARE
*
ERROR at line 1:
ORA-23627: Comparison object "TESTUSER"."COMP_EMP" already existed.
ORA-06512: at "SYS.DBMS_COMPARISON", line 4793
ORA-06512: at "SYS.DBMS_COMPARISON", line 448
ORA-06512: at line 8


Errr.. Let us delete the comparison object  and try again

SQL> exec dbms_comparison.drop_comparison(comparison_name => 'comp_emp');

PL/SQL procedure successfully completed.

SQL>

SQL> DECLARE
  2    scan_info  dbms_comparison.comparison_type;
  3    scan_id    INTEGER;
  4    consistent BOOLEAN;
  5  BEGIN
  6
  7    --  dbms_comparison.drop_comparison(comparison_name => 'comp_emp');
  8    dbms_comparison.create_comparison(comparison_name    => 'comp_emp',
  9                                      schema_name        => 'testuser',
 10                                      object_name        => 'emp',
 11                                      dblink_name        => 'remotedb_link',
 12                                      remote_schema_name => 'srcuser',
 13                                      remote_object_name => 'emp');
 14
 15    consistent := dbms_comparison.compare(comparison_name => 'comp_emp',
 16                                          scan_info       => scan_info);
 17
 18    IF consistent = TRUE THEN
 19      dbms_output.put_line('No differences were found.');
 20    ELSE
 21      dbms_output.put_line('Differences were found.');
 22    END IF;
 23
 24    dbms_comparison.converge(comparison_name  => 'comp_emp',
 25                             scan_id          => scan_info.scan_id,
 26                             scan_info        => scan_info,
 27                             converge_options => dbms_comparison.CMP_CONVERGE_REMOTE_WINS);
 28
 29    dbms_output.put_line('Scan ID: ' || scan_info.scan_id);
 30    dbms_output.put_line('Local Rows Merged:' || scan_info.loc_rows_merged);
 31    dbms_output.put_line('Remote Rows Merged:' || scan_info.rmt_rows_merged);
 32    dbms_output.put_line('Local Rows Deleted:' || scan_info.loc_rows_deleted);
 33    dbms_output.put_line('Remote Rows Deleted:' ||
 34                         scan_info.rmt_rows_deleted);
 35  END;
 36  /
No differences were found.
Scan ID: 4
Local Rows Merged:0
Remote Rows Merged:0
Local Rows Deleted:0
Remote Rows Deleted:0

PL/SQL procedure successfully completed.

SQL> delete from emp where empno = 7934;

1 row deleted.

SQL> commit;
Commit complete.


SQL>  exec dbms_comparison.drop_comparison(comparison_name => 'comp_emp');
PL/SQL procedure successfully completed.

SQL> DECLARE
  2    scan_info  dbms_comparison.comparison_type;
  3    scan_id    INTEGER;
  4    consistent BOOLEAN;
  5  BEGIN
  6
  7      --  dbms_comparison.drop_comparison(comparison_name => 'comp_emp');
  8      dbms_comparison.create_comparison(comparison_name    => 'comp_emp',
  9                                      schema_name        => 'testuser',
 10                                      object_name        => 'emp',
 11                                      dblink_name        => 'remotedb_link',
 12                                      remote_schema_name => 'srcuser',
 13                                      remote_object_name => 'emp');
 14
 15    consistent := dbms_comparison.compare(comparison_name => 'comp_emp',
 16                                          scan_info       => scan_info);
 17
 18    IF consistent = TRUE THEN
 19      dbms_output.put_line('No differences were found.');
 20    ELSE
 21      dbms_output.put_line('Differences were found.');
 22    END IF;
 23
 24    dbms_comparison.converge(comparison_name  => 'comp_emp',
 25                             scan_id          => scan_info.scan_id,
 26                             scan_info        => scan_info,
 27                             converge_options => dbms_comparison.CMP_CONVERGE_REMOTE_WINS);
 28
 29    dbms_output.put_line('Scan ID: ' || scan_info.scan_id);
 30    dbms_output.put_line('Local Rows Merged:' || scan_info.loc_rows_merged);
 31    dbms_output.put_line('Remote Rows Merged:' || scan_info.rmt_rows_merged);
 32    dbms_output.put_line('Local Rows Deleted:' || scan_info.loc_rows_deleted);
 33    dbms_output.put_line('Remote Rows Deleted:' ||
 34                         scan_info.rmt_rows_deleted);
 35  END;
 36  /
Differences were found.
Scan ID: 5
Local Rows Merged:1
Remote Rows Merged:0
Local Rows Deleted:0
Remote Rows Deleted:0

PL/SQL procedure successfully completed.