1. 程式人生 > 其它 >Oracle載體伺服器遷移後,資料一致性校驗指令碼

Oracle載體伺服器遷移後,資料一致性校驗指令碼

目錄

1 伺服器遷移後資料量對(表、檢視、索引、儲存過程、函式、包體)比較

-- (1) 當前使用者表總數量新舊差異
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'TABLE' PROJECT_NAME FROM DBA_OBJECTS T WHERE T.OBJECT_TYPE='TABLE'   AND T.OWNER = 'xxx' 
MINUS
SELECT 'xxx'                NAME, COUNT(1)  C_COUNT, 'TABLE' PROJECT_NAME FROM DBA_OBJECTS@DB_LINK T WHERE T.OBJECT_TYPE='TABLE'   AND T.OWNER = 'xxx' 

-- (2) 當前檢視總數量新舊差異
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'VIEW' PROJECT_NAME FROM DBA_OBJECTS T WHERE T.OBJECT_TYPE='VIEW'   AND T.OWNER = 'xxx' 
MINUS
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'VIEW' PROJECT_NAME FROM DBA_OBJECTS@DB_LINK T WHERE T.OBJECT_TYPE='VIEW'   AND T.OWNER = 'xxx'

-- (3) 當前儲存過程總數量新舊差異
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'PROCEDURE' PROJECT_NAME FROM DBA_OBJECTS T WHERE T.OBJECT_TYPE='PROCEDURE'   AND T.OWNER = 'xxx'  
MINUS
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'PROCEDURE' PROJECT_NAME FROM DBA_OBJECTS@DB_LINK T WHERE T.OBJECT_TYPE='PROCEDURE'   AND T.OWNER = 'xxx' 

-- (4) 當前包體總數量新舊差異
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'PACKAGE BODY' PROJECT_NAME FROM DBA_OBJECTS T WHERE T.OBJECT_TYPE='PACKAGE BODY'   AND T.OWNER = 'xxx' 
MINUS
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'PACKAGE BODY' PROJECT_NAME FROM DBA_OBJECTS@DB_LINK T WHERE T.OBJECT_TYPE='PACKAGE BODY'   AND T.OWNER = 'xxx'  

-- (5) 當前索引總數量新舊差異
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'INDEX' PROJECT_NAME FROM DBA_OBJECTS T WHERE T.OBJECT_TYPE='INDEX'   AND T.OWNER = 'xxx'
MINUS
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'INDEX' PROJECT_NAME FROM DBA_OBJECTS@DB_LINK T WHERE T.OBJECT_TYPE='INDEX'   AND T.OWNER = 'xxx' 


-- (6) 當前函式總數量新舊差異
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'FUNCTION' PROJECT_NAME FROM DBA_OBJECTS T WHERE T.OBJECT_TYPE='FUNCTION'   AND T.OWNER = 'xxx' 
MINUS
SELECT 'xxx' NAME, COUNT(1)  C_COUNT, 'FUNCTION' PROJECT_NAME FROM DBA_OBJECTS@DB_LINK T WHERE T.OBJECT_TYPE='FUNCTION'   AND T.OWNER = 'xxx'

2 查詢程式體新舊伺服器差異

-- 獲取當前使用者下包體資料量差異

-- SELECT * FROM ALL_SOURCE  where TYPE='PACKAGE BODY' AND  OWNER='xxx' and name='xxx';


-- (1) 建立輔助表
-- 輔助表1
/*-- Create table
create table T_MINUS_ERROR_INFO
(
user_name VARCHAR2(100),
type_name VARCHAR2(100),
name1     VARCHAR2(100)
)

-- Add comments to the columns 
comment on column T_MINUS_ERROR_INFO.user_name
is '使用者';
comment on column T_MINUS_ERROR_INFO.type_name
is '型別:PROCEDURE 、FUNCTION 、PACKAGE BODY';
comment on column T_MINUS_ERROR_INFO.name1
is '名稱:PROCEDURE-xxx、FUNCTION-xxx 、PACKAGE BODY-xxx';*/
-- 輔助表2
/*create table t_minus_tmp(
     text varchar2(4000)
)*/

-- (2)對單個使用者下的PROCEDURE 、FUNCTION 、PACKAGE BODY  、PACKAGE 內容進行比較
--  引數說明:
--           V_USER := 'xxx'  -- 使用者
--           V_DBLINK := 'DB_LINK'  -- DBLINK
DECLARE 
  V_USER VARCHAR2(20); -- 定義使用者
  V_SQL_STR VARCHAR2(4000);
  CURSOR C_TYPE IS SELECT DISTINCT TYPE FROM ALL_SOURCE;
  V_TYPE ALL_SOURCE.TYPE%TYPE; -- 定義型別
  V_COUNT VARCHAR2(10);
  V_DBLINK VARCHAR2(10);
BEGIN
  V_USER := 'xxx';
  V_DBLINK := 'DB_LINK'
  -- 獲取大類:PROCEDURE 、FUNCTION 、PACKAGE BODY  、PACKAGE
  EXECUTE IMMEDIATE 'TRUNCATE TABLE T_MINUS_ERROR_INFO';-- 清除輔助表T_MINUS_TMP
  
  OPEN C_TYPE;
  LOOP
       FETCH C_TYPE INTO V_TYPE;
       EXIT WHEN C_TYPE%NOTFOUND;
       
       IF V_TYPE = 'PROCEDURE' OR V_TYPE = 'FUNCTION' OR V_TYPE = 'PACKAGE' OR V_TYPE='PACKAGE BODY'  THEN
           --  SELECT DISTINCT NAME FROM ALL_SOURCE  where TYPE='PACKAGE BODY' AND  OWNER='xxx' ;
            -- SELECT * FROM ALL_SOURCE  where TYPE='PACKAGE BODY' AND  OWNER='xxx' AND NAME='xxx';
            -- 獲取包體的名稱D
            DECLARE 
                CURSOR C_PACKAGE_BODY_NAME IS SELECT DISTINCT NAME FROM ALL_SOURCE WHERE TYPE=V_TYPE AND  OWNER=V_USER;
                V_BODY_NAME ALL_SOURCE.NAME%TYPE;
            BEGIN
                OPEN C_PACKAGE_BODY_NAME;
                LOOP
                     FETCH C_PACKAGE_BODY_NAME INTO V_BODY_NAME;
                     EXIT WHEN C_PACKAGE_BODY_NAME%NOTFOUND;
                     EXECUTE IMMEDIATE 'TRUNCATE TABLE T_MINUS_TMP';-- 清除輔助表T_MINUS_TMP
                     
                     V_SQL_STR := 'INSERT INTO T_MINUS_TMP SELECT TEXT FROM ALL_SOURCE WHERE TYPE='||''''||V_TYPE||''''||' AND OWNER='||''''||V_USER||''''||' AND NAME='||''''||V_BODY_NAME||''''||' MINUS '||
                                  ' SELECT TEXT FROM ALL_SOURCE'||'@'||V_DBLINK||' WHERE TYPE='||''''||V_TYPE||''''||' AND OWNER='||''''||V_USER||''''||' AND NAME='||''''||V_BODY_NAME||'''';
                      DBMS_OUTPUT.PUT_LINE(V_SQL_STR);
                     
                     EXECUTE IMMEDIATE V_SQL_STR;  -- 執行動態sql,並將結果寫入結果表
                     COMMIT;
                     SELECT COUNT(1) INTO V_COUNT FROM T_MINUS_TMP;
                     
                     -- 對資料進行統計,判斷差異
                     IF V_COUNT <> 0 THEN 
                        DBMS_OUTPUT.PUT_LINE(V_USER||'.'||V_TYPE||'.'||V_BODY_NAME||' 存在差異');
                        INSERT INTO T_MINUS_ERROR_INFO(
                               USER_NAME,
                               TYPE_NAME,
                               NAME1
                        )
                        SELECT V_USER,V_TYPE,V_BODY_NAME FROM DUAL;
                        COMMIT;
                     ELSE
                        DBMS_OUTPUT.PUT_LINE(V_USER||'.'||V_TYPE||'.'||V_BODY_NAME||' 不存在差異');
                     END IF;

                END LOOP;
                CLOSE C_PACKAGE_BODY_NAME;
                 
            END;
       
       END IF;
       
  END LOOP;
  CLOSE C_TYPE;
  
END;


-- (3) 查詢錯誤記錄,資訊包含了 使用者,型別,型別體的名字
select * from T_MINUS_ERROR_INFO

3 查詢使用者下各表中新舊伺服器總資料差異

-- 按順序使用

-- (1) 建立輔助表
-- Create table
/*create table T_TMP_CY
(
table_name VARCHAR2(100),
c_count    NUMBER
)
*/

--(2)獲取該使用者下各表,新舊伺服器中資料量差異

DECLARE
V_SQL_STR VARCHAR2(5000); 
V_USER_NAME VARCHAR2(100);
V_DBLINK VARCHAR2(100); 
V_COUNT VARCHAR2(20);

BEGIN
V_USER_NAME := 'xxx';--確定使用者名稱 
V_DBLINK := 'DB_LINK';--確定DB_LINK 

DECLARE
   CURSOR C_CURSOR IS SELECT TABLE_NAME FROM DBA_TABLES WHERE OWNER=V_USER_NAME; 
   V_TABLE_NAME DBA_TABLES.TABLE_NAME%TYPE;
BEGIN
  
   EXECUTE IMMEDIATE 'TRUNCATE TABLE T_TMP_CY'; 
   OPEN C_CURSOR;
   LOOP
       FETCH C_CURSOR INTO V_TABLE_NAME; 
       EXIT WHEN C_CURSOR%NOTFOUND;
       V_SQL_STR := 'INSERT INTO T_TMP_CY'||' SELECT '||''''||V_USER_NAME||'.'||V_TABLE_NAME||''''||' TABLE_NAME, COUNT(1) C_COUNT FROM '||V_USER_NAME||'.'||V_TABLE_NAME||' MINUS '||
                    ' SELECT '||''''||V_USER_NAME||'.'||V_TABLE_NAME||''''||' TABLE_NAME, COUNT(1) C_COUNT FROM '||V_USER_NAME||'.'||V_TABLE_NAME||'@'||V_DBLINK;
       -- DBMS_OUTPUT.PUT_LINE(V_SQL_STR);
       EXECUTE IMMEDIATE V_SQL_STR;
       COMMIT;
       
       SELECT C_COUNT INTO V_COUNT FROM T_TMP_CY WHERE TABLE_NAME=V_USER_NAME||'.'||V_TABLE_NAME;
       
       IF V_COUNT<>0 THEN
          DBMS_OUTPUT.PUT_LINE(V_USER_NAME||'.'||V_TABLE_NAME||'的差異量:'||V_COUNT||'  需要修正');
       END IF;
       
   END LOOP;
   CLOSE C_CURSOR;
   
END;
END;


-- (2)獲取差異資料
SELECT * FROM T_TMP_CY;