Área de Tecnologías de la Información y las Comunicaciones Aplicadas
Área de Tecnologías de la Información y las Comunicaciones Aplicadas Universidad de Murcia
Área de Tecnologías de la Información y las Comunicaciones Aplicadas
ATICA arrow DBCONNECTOR arrow DBA - Comparar Objetos entre dos Bases de Datos
21.09.2017
 
 
DBA - Comparar Objetos entre dos Bases de Datos Imprimir E-mail

Oracle 11g proporciona el paquete DBMS_COMPARISON para comparar el contenido de dos objetos (tablas o vistas) que incluso pueden estar en bases de datos diferentes.

Normalmente se usa para encontrar las diferencias en el contenido entre objetos de dos bases de datos, para después hacerlos converger, replicando las diferencias en una de las dos bases de datos.


Cómo se usa

Los pasos básicos para usar el paquete DBMS_COMPARISON son:

  • Crear la comparación con el procedimiento CREATE_COMPARE: identificando los objetos a comparar y definiendo los parámetros de la comparación.
  • Ejecutar la función COMPARE para comparar los objetos e identificar las diferencias. Esta función devuelve TRUE si los objetos son iguales y FALSE en caso contrario, y además, guarda los resultados detallados de la comparación en el Diccionario de Datos (DD). Cada vez que se ejecute la función COMPARE se genera un juego diferente de resultados en el DD.
  • Para ver los resultados detallados de la comparación hay que consultar las vistas:
    • DBA_COMPARISON / USER_COMPARISON
    • DBA_COMPARISON_COLUMNS / USER_COMPARISON_COLUMNS
    • DBA_COMPARISON_SCAN / USER_COMPARISON_SCAN

    • DBA_COMPARISON_SCAN_SUMMARY / USER_COMPARISON_SCAN_SUMMARY
    • DBA_COMPARISON_SCAN_VALUES /USER_COMPARISON_SCAN_VALUES

    • DBA_COMPARISON_ROW_DIF /USER_COMPARISON_ROW_DIF

  • Si hay diferencias, puedes sincronizar ambas bases de datos ejecutando el procedimiento CONVERGE.

Ejemplos

Veamos un Primer Ejemplo con la tabla DEPT del esquema SCOTT:

Primero creamos la tabla en otro esquema a partir de la anterior, y hacemos que difieran en el contenido, borrando alguna fila:

CREATE TABLE dept AS SELECT * FROM scott.dept;
Table created.

DELETE FROM dept WHERE rownum = 1;
1 row deleted.

COMMIT;
Commit complete.

Creamos la comparación para la tabla DEPT de SCOTT y la nueva (que hemos creado en el esquema USUARIO de la misma BD), y la llamamos COMPARADEPT:
set serveroutput on

exec dbms_comparison.create_comparison(comparison_name=>'COMPARADEPT', schema_name=>'SCOTT', object_name=>'DEPT', dblink_name=>NULL, remote_schema_name=>'USUARIO', remote_object_name=>'DEPT', scan_percent=>90);

*
ERROR at line 1:
ORA-23626: No eligible index on table SCOTT.DEPT
El error ORA-23626 se debe a que no hemos creado el índice correspondiente a las PK en la copia de la tabla, así que lo creamos y volvemos a ejecutar CREATE _COMPARISON:
alter table dept add CONSTRAINT  pk_dept_usuario PRIMARY KEY (DEPTNO);
Table altered.

EXEC dbms_comparison.create_comparison(comparison_name=>'COMPARADEPT', schema_name=>'SCOTT', object_name=>'DEPT', dblink_name=>NULL, remote_schema_name=>'USUARIO', remote_object_name=>'DEPT', scan_percent=>90)

PL/SQL procedure successfully completed.
Ahora vamos a comprobar, en el DD, los datos de la comparación que hemos lanzado:
SELECT comparison_name, comparison_mode, schema_name, object_name, remote_schema_name, remote_object_name, scan_percent from user_comparison;

COMP_NAME COMP_MODE SCHEMA_NAME OBJECT_NAME REMOTE_SCHEMA REMOTE_OBJECT SCAN_PERCENT
----------- --------- ----------- ----------- ------------- ------------- ------------
COMPARADEPT    TABLE        SCOTT        DEPT    USUARIO           DEPT


SELECT comparison_name, column_position, column_name, index_column
FROM user_comparison_columns;

COMPARISON_NAME COLUMN_POSITION COLUMN_NAME INDEX_COLUMN
--------------- --------------- ----------- ------------
COMPARADEPT              1        EPTNO     Y
COMPARADEPT              2        DNAME     N
COMPARADEPT              3        LOC       N

6 rows selected.
Entonces usamos la función COMPARE para ver si hay diferencias, y si las hay las consultamos en las vistas correspondientes del DD:
DECLARE
  retval dbms_comparison.comparison_type;
BEGIN
  IF dbms_comparison.compare('COMPARADEPT', retval, perform_row_dif=>TRUE) THEN
     dbms_output.put_line('No hay Diferencias');
  ELSE
     dbms_output.put_line('Diferencias Encontradas');
  END IF;
END;
/
Diferencias Encontradas

PL/SQL procedure successfully completed.


SELECT COMPARISON_NAME, scan_id, COUNT_ROWS, status from user_comparison_scan;

COMPARISON_NAME SCAN_ID COUNT_ROWS STATUS
--------------- ------- ---------- ----------------
COMPARADEPT         1        4     BUCKET DIF
COMPARADEPT         2        2     ROW DIF


select COMPARISON_NAME, SCAN_ID, LOCAL_ROWID, REMOTE_ROWID, STATUS from user_comparison_row_dif;

COMPARISON_NAME SCAN_ID LOCAL_ROWID       REMOTE_ROWID STATUS
--------------- ------- -----------       ------------ ------
COMPARADEPT           2 AACbX/AABAAA8pKAAA          DIF


SELECT css.scan_id, uc.comparison_name, uc.schema_name, uc.object_name, css.current_dif_count
FROM user_comparison uc, user_comparison_scan_summary css
WHERE uc.comparison_name = css.comparison_name
AND css.scan_id = 2;

   SCAN_ID COMPARISON_NAME SCHEMA_NAM OBJECT_NAM CURRENT_DIF_COUNT
---------- --------------- ---------- ---------- -----------------
         2 COMPARADEPT       SCOTT      DEPT               1


SELECT ucc.column_name, ucrd.index_value,
  CASE WHEN ucrd.local_rowid IS NULL THEN 'No'
  ELSE 'Yes'
  END AS LOCAL_ROWID,
  CASE WHEN ucrd.REMOTE_ROWID IS NULL THEN 'No'
  ELSE 'Yes'
  END AS REMOTE_ROWID
 FROM user_comparison_columns ucc, user_comparison_row_dif ucrd, user_comparison_scan ucs
WHERE ucrd.scan_id = ucs.scan_id
  AND ucc.comparison_name = ucrd.comparison_name
  AND ucc.comparison_name = 'COMPARADEPT'
  AND ucrd.status = 'DIF'
  AND ucc.INDEX_COLUMN = 'Y'
ORDER BY 2;

COLUMN_NAME INDEX_VALUE LOC REM
----------- ----------- --- ---
DEPTNO        10        Yes No

Por tanto, como se observa claramente en la ultima consulta, la tabla local (SCOTT.DEPT) tiene una fila que no esta en la tabla remota (USUARIO.DEPT), que es la que tiene DEPTNO=10.

Ahora vamos a hacer converger la tabla local en la remota ("Local Wins"), y para ello usaremos el procedimiento CONVERGE indicando los parámetros COMPARISON_NAME='COMPARADEPT', SCAN_ID=2, y CONVERGE_OPTIONS=DBMS_COMPARISON.CMP_CONVERGE_LOCAL_WINS (si en lugar de convertir la tabla remota en la local, queremos que se apliquen los cambios necesarios en la local para que sea igual que la remota, indicaremos DBMS_COMPARISON.CMP_CONVERGE_REMOTE_WINS):

select * from dept where deptno=10;
no rows selected

declare
  compare_info dbms_comparison.comparison_type;
begin
  dbms_comparison.converge (
       comparison_name=>'COMPARADEPT',
       scan_id=>2,
       scan_info=>compare_info,
       converge_options=>dbms_comparison.cmp_converge_local_wins);
       dbms_output.put_line('--- Resultados ---');
       dbms_output.put_line('Filas Locales modificadas: '||compare_info.loc_rows_merged);
       dbms_output.put_line('Filas Remotas modificadas: '||compare_info.rmt_rows_merged);
       dbms_output.put_line('Filas Locales Borradas: '||compare_info.loc_rows_deleted);
       dbms_output.put_line('Filas Remotas Borradas: '||compare_info.rmt_rows_deleted);
end;
/

--- Resultados ---
Filas Locales modificadas: 0
Filas Remotas modificadas: 1
Filas Locales Borradas: 0
Filas Remotas Borradas: 0


select * from dept where deptno=10;

    DEPTNO DNAME      LOC
---------- -------------- -------------
    10 ACCOUNTING      NEW YORK
Finalmente podemos borrar la comparacion usando DROP_COMPARISON:
select COMPARISON_NAME FROM USER_COMPARISON;

COMPARISON_NAME
------------------------------
COMPARADEPT


exec DBMS_COMPARISON.DROP_COMPARISON(comparison_name => 'COMPARADEPT')
PL/SQL procedure successfully completed.

select COMPARISON_NAME FROM USER_COMPARISON;
no rows selected

Veamos un Segundo Ejemplo con también con la tabla DEPT del esquema SCOTT, pero esta vez la vamos a comparar con USUARIO.DEPT que esta vez reside en una BD remota. Además las filas de las 2 tablas tienen valores completamente distintos para la columna DEPTNO. El objetivo esta vez es hacer que la tabla local (SCOTT.DEPT) tenga el mismo contenido que la remota (USUARIO.DEPT), y por tanto en el CONVERGE usaremos "dbms_comparison.cmp_converge_remote_wins". Fíjate además, que esta vez hay 2 "comparison scans" del tipo "row dif", de modo que tendremos que ejecutar CONVERGE para cada una de dichos "scans":

select * from dept;

    DEPTNO DNAME      LOC
---------- -------------- -------------
    20 RESEARCH      DALLAS
    30 SALES      CHICAGO
    40 OPERATIONS      BOSTON

select * from dept@dl_usuario_bdremota;

    DEPTNO DNAME      LOC
---------- -------------- -------------
    11 ACCOUNTING      NEW YORK
    21 RESEARCH      DALLAS
    31 SALES      CHICAGO
    41 OPERATIONS      BOSTON

exec dbms_comparison.create_comparison(comparison_name=>'COMPARADEPT', schema_name=>'USUARIO', object_name=>'DEPT', dblink_name=>'DL_USUARIO_BDREMOTA', remote_schema_name=>'USUARIO', remote_object_name=>'DEPT')

PL/SQL procedure successfully completed.

SELECT comparison_name, column_position, column_name, index_column
FROM user_comparison_columns;

COMPARISON_NAME COLUMN_POSITION COLUMN_NAME               I
--------------- --------------- ------------------------------ -
COMPARADEPT              1 DEPTNO                   Y
COMPARADEPT              2 DNAME                   N
COMPARADEPT              3 LOC                   N

SELECT COMPARISON_NAME, scan_id, COUNT_ROWS, status from user_comparison_scan;

COMPARISON_NAME    SCAN_ID COUNT_ROWS STATUS
--------------- ---------- ---------- ----------------
COMPARADEPT        42        4 BUCKET DIF
COMPARADEPT        43        2 ROW DIF
COMPARADEPT        44        2 ROW DIF

select COMPARISON_NAME, SCAN_ID, LOCAL_ROWID, REMOTE_ROWID, STATUS from user_comparison_row_dif;

COMPARISON_NAME    SCAN_ID LOCAL_ROWID          REMOTE_ROWID     STA
--------------- ---------- ------------------ ------------------ ---
COMPARADEPT        43              AAA72pAAFAAAAVyAAA DIF
COMPARADEPT        43              AAA72pAAFAAAAVyAAB DIF
COMPARADEPT        43 AAD599AAFAAAAl+AAB             DIF
COMPARADEPT        44              AAA72pAAFAAAAVyAAC DIF
COMPARADEPT        44              AAA72pAAFAAAAVyAAD DIF
COMPARADEPT        44 AAD599AAFAAAAl+AAD             DIF
COMPARADEPT        44 AAD599AAFAAAAl+AAC             DIF

7 rows selected.

!cat compare_converge.sql
 -- Hace el converge con el scan que pasemos como parámetro
 declare

  compare_info dbms_comparison.comparison_type;
 begin
  dbms_comparison.converge (
       comparison_name=>'COMPARADEPT',
       scan_id=>&&1,
       scan_info=>compare_info,
       converge_options=>dbms_comparison.cmp_converge_remote_wins);
       dbms_output.put_line('--- Resultados ---');
       dbms_output.put_line('Filas Locales modificadas: '||compare_info.loc_rows_merged);
       dbms_output.put_line('Filas Remotas modificadas: '||compare_info.rmt_rows_merged);
       dbms_output.put_line('Filas Locales Borradas: '||compare_info.loc_rows_deleted);
       dbms_output.put_line('Filas Remotas Borradas: '||compare_info.rmt_rows_deleted);
end;
/

@compare_converge.sql 44
--- Resultados ---
Filas Locales modificadas: 2
Filas Remotas modificadas: 0
Filas Locales Borradas: 2
Filas Remotas Borradas: 0

PL/SQL procedure successfully completed.

select *  from dept;

    DEPTNO DNAME      LOC
---------- -------------- -------------
    31 SALES      CHICAGO
    20 RESEARCH      DALLAS
    41 OPERATIONS      BOSTON

@compare_converge.sql 43
--- Resultados ---
Filas Locales modificadas: 2
Filas Remotas modificadas: 0
Filas Locales Borradas: 1
Filas Remotas Borradas: 0

PL/SQL procedure successfully completed.

select *  from dept;

    DEPTNO DNAME      LOC
---------- -------------- -------------
    31 SALES      CHICAGO
    41 OPERATIONS      BOSTON
    11 ACCOUNTING      NEW YORK
    21 RESEARCH      DALLAS

select *  from dept@dl_usuario_bdremota;

    DEPTNO DNAME      LOC
---------- -------------- -------------
    11 ACCOUNTING      NEW YORK
    21 RESEARCH      DALLAS
    31 SALES      CHICAGO
    41 OPERATIONS      BOSTON;

Enlaces


Última modificación ( 13.06.2012 )
 
Área de Tecnologías de la Información y las Comunicaciones Aplicadas
Volver al incio del documento Volver al inicio del documento
Área de Tecnologías de la Información y las Comunicaciones Aplicadas