程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> 談oracle數據比對(DBMS_COMPARISON)

談oracle數據比對(DBMS_COMPARISON)

編輯:Oracle教程

談oracle數據比對(DBMS_COMPARISON)


今天是2014-08-19,我今天收到csdn給我發的申請博客專家的邀請,自己感覺實在慚愧啊。自從換了工作也一直沒有精力在寫點東西了。今天我一個同事,在群裡貼出了一個數據比對的包(DBMS_COMPARISON),但是這個包相比用的比較少。所以今天就談談這個工具包的使用吧。

對於經常完數據遷移的朋友來說,在數據挪動之後,最重要也是最關鍵和最關心的一個問題是,目標端和源端的數據是否一致。數據的一致是否關系著大型oracle數據庫數據遷移的成敗與否。目前很多公司都開始研發自己的對比工具,如dsg的基於rowid的比對、基於minus的比對等等。但是數據庫本身也是給我們提供了一個數據比對的接口,那就是這個DBMS_COMPARISON軟件包。

DBMS_COMPARISION簡介:

這個軟件包是oracle提供的可以再兩個數據之間做object是比對。並且呢如果在比對過程中如果源端數據和目標端數據不一致,那麼可以選擇是從源端在將數據復制到目標端,還是從目標端在復制到源端,最終達到數據一致性的結果。該包也是通過創建dblink來實現的。這個工具的使用大體分為四步:

第一步:使用create_compare去創建一個比對動作

第二步:使用compare函數去進行數據對象之間的比對

第三步:我們在去查看比對結果,相應的record會記錄到不同視圖中如下:

DBA_COMPARISON_SCAN

USER_COMPARISON_SCAN

DBA_COMPARISON_SCAN_VALUES

USER_COMPARISON_SCAN_VALUES

DBA_COMPARISON_ROW_DIF

USER_COMPARISON_ROW_DIF

第四不:如果數據不一致,那麼可以使用convert去將數據同步

大家可能會說,如果我進行了兩次數據比對,那麼如何區分呢,這就是oracle自己會給你設計一個標示了。這個函數是recheck。後續介紹:

還有一個問題,那就是這個包能做哪些數據比對?

答案是:對表、視圖、物化視圖、同義詞等

DBMS_COMPARISION限制:

當然了任何一個工具都有自己的限制,那麼這個包呢?

1、對於源端數據庫版本必須是高於11.1,對於目標端數據庫版本必須高於10.1

2.對於所有比對的數據庫對象,必須是共享對象,也就是說每個對象的列個數和列的類型必須一致。如果列不一致,那麼需要將比對的列使用column_list做個列表。

Database objects of different types can be compared and converged at different databases. For example, a table at one database and a materialized view at another database can be compared and converged with this package.

以上是說了比較容易理解的限制,下面在說一下索引列的限制:

1、在全庫比對模式下,必須要有一個在 number, timestamp, interval, or DATE 數據類型的單一索引列,或是僅僅有一個包括這幾種數據類型的復合索引,但是這個復合索引中設計到的列必須都是not null或是其中一列是一個主鍵列。

2、

For the scan modes CMP_SCAN_MODE_FULL and CMP_SCAN_MODE_CUSTOM to be supported, the database objects must have one of the following types of indexes:

A single-column index on a number, timestamp, interval, DATE, VARCHAR2, or CHAR data type column

A composite index that only includes number, timestamp, interval, DATE, VARCHAR2, or CHAR columns. Each column in the composite index must either have a NOT NULL constraint or be part of the primary key.

如果數據庫沒有滿足這些要求,那麼這個包將無法進行數據比對。

if the database objects have only one index, and it is a composite index that includes a NUMBER column and an NCHAR column, then the DBMS_COMPARISON package does not support them.

If these constraints are not present on a table, then use the index_schema_name and index_name parameters in the CREATE_COMPARISON procedure to specify an index whose columns satisfy this requirement.

When a single index value identifies both a local row and a remote row, the two rows must be copies of the same row in the replicated tables. In addition, each pair of copies of the same row must always have the same index value.

DBms_comparison不支持的數據類型:

LONG、LANG RAW、ROWID、urowid、clob、nclob、blob、bfile另外還有如下兩種:

1、udt(user-defined types,including object types, REFs, varrays, and nested tables)

2、oracle-supplied type (including any types, XML types, spatial types, and media types)

好了,了解這些後,我們就開始去親自做一下,光說不練那不行。

第一創建dblink:

SQL> select * from dba_sys_privs rhys where rhys.privilege like upper('%link%');

GRANTEE                        PRIVILEGE                                ADM
------------------------------ ---------------------------------------- ---
SYS                            DROP PUBLIC DATABASE LINK                NO
SYS                            CREATE DATABASE LINK                     NO
OWB$CLIENT                     CREATE DATABASE LINK                     NO
IMP_FULL_DATABASE              CREATE PUBLIC DATABASE LINK              NO
RECOVERY_CATALOG_OWNER         CREATE DATABASE LINK                     NO
DBA                            DROP PUBLIC DATABASE LINK                YES
IMP_FULL_DATABASE              DROP PUBLIC DATABASE LINK                NO
OWBSYS                         CREATE DATABASE LINK                     YES
IMP_FULL_DATABASE              CREATE DATABASE LINK                     NO
SYS                            CREATE PUBLIC DATABASE LINK              NO
DBA                            CREATE PUBLIC DATABASE LINK              YES

GRANTEE                        PRIVILEGE                                ADM
------------------------------ ---------------------------------------- ---
DBA                            CREATE DATABASE LINK                     YES

12 rows selected.

SQL> grant create database link to scott;

Grant succeeded.
SQL> create database link comparison_link connect to scott identified by root using 'orac1';

Database link created.

SQL> show user
USER is "SCOTT"
SQL> select * from scott.emp@comparison_link;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO DEP
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- ------------------------------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
      7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO DEP
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- ------------------------------
      7902 AMY        ANALYST         7566 03-DEC-81       3000                    20

12 rows selected.

SQL> 

第二步創建比對任務:

對了忘記提一下權限了,對於該包,要有如下權限:

SQL> grant execute on dbms_comparison to scott;

Grant succeeded.

SQL> grant execute_catalog_role to scott;

Grant succeeded.

SQL> 
SQL>  begin
  2   dbms_comparison.create_comparison(
  3   comparison_name=>'test1',
  4   schema_name=>'SCOTT',
  5   object_name=>'DEPT',
  6   dblink_name=>'comparison_link'
  7   );
  8   end;
  9  /

PL/SQL procedure successfully completed.

SQL> 

好這樣就做完第一步了。

當源端和目標端數據對象的列不一致的情況會出現如下錯誤:

SQL>  begin
  2   dbms_comparison.create_comparison(
  3   comparison_name=>'test1',
  4   schema_name=>'SCOTT',
  5   object_name=>'EMP',
  6   dblink_name=>'comparison_link'
  7   );
  8   end;
  9  /
 begin
*
ERROR at line 1:
ORA-23625: Table shapes of SCOTT.EMP and SCOTT.EMP@COMPARISON_LINK did not match.
ORA-06512: at "SYS.DBMS_COMPARISON", line 5008
ORA-06512: at "SYS.DBMS_COMPARISON", line 448
ORA-06512: at line 2

那麼怎麼辦呢?和我說的是做一個column_list;

第二步開始進行數據比對:

SQL> declare
  2   compare_info dbms_comparison.comparison_type;
  3   compare_return boolean;
  4   begin
  5   compare_return := dbms_comparison.compare (comparison_name=>'test1',
  6   scan_info=>compare_info,
  7   perform_row_dif=>TRUE);
  8   
  9  if compare_return=TRUE
 10   then
 11   dbms_output.put_line('the tables are equivalent.');
 12   else
 13   dbms_output.put_line('Bad news... there is data divergence.');
 14   dbms_output.put_line('Check the dba_comparison and dba_comparison_scan_summary views for locate the differences for scan_id:'||compare_info.scan_id);
 15   end if;
 16   end;
 17   /
the tables are equivalent.

PL/SQL procedure successfully completed.

SQL> 

第三步查看比對結果:

SQL> select * from user_comparison_scan
  2  ;

COMPARISON_NAME         SCAN_ID PARENT_SCAN_ID ROOT_SCAN_ID STATUS           CURRENT_DIF_COUNT INITIAL_DIF_COUNT COUNT_ROWS S LAST_UPDATE_TIME
-------------------- ---------- -------------- ------------ ---------------- ----------------- ----------------- ---------- - ----------------------------------------
TEST1                         1                           1 SUC                              0                 0          4 N 19-AUG-14 11.05.42.780593 PM
TEST1                         2                           2 SUC                              0                 0          4 N 19-AUG-14 11.11.37.613343 PM

SQL> select * from user_comparison_row_dif;

no rows selected

SQL>

好了,簡簡單單就到這了。

當然如果敢興趣可以自己在測試其他的。

我要把數據清掉了:

SQL> begin
  2  dbms_comparison.purge_comparison(
  3  comparison_name=>'test1');
  4  end;
  5  /

PL/SQL procedure successfully completed.

SQL> select * from user_comparison_scan;

no rows selected

SQL> 

that's all!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved