今天同事提出了一個(gè)問題:
使用數(shù)據(jù)泵expdp導(dǎo)出1個(gè)schema,有個(gè)表主鍵是觸發(fā)器自增的id,導(dǎo)入測試庫測試時(shí),發(fā)現(xiàn)表里的數(shù)據(jù)比自增序列的值要大。導(dǎo)致插入數(shù)據(jù)報(bào)錯(cuò)。
最終結(jié)論是:
由于數(shù)據(jù)庫先進(jìn)行序列導(dǎo)出,然后再進(jìn)行表數(shù)據(jù)導(dǎo)出。然后在導(dǎo)出的過程中,該表一直有插入操作,最終導(dǎo)致了這種差異。
解決方法:
重建觸發(fā)器中的序列,讓序列的開始值為表主鍵最大值+1。

下面我構(gòu)造實(shí)驗(yàn)完整演示下這種場景。

1.準(zhǔn)備測試環(huán)境

需要建立測試表,序列,觸發(fā)器和模擬業(yè)務(wù)插入數(shù)據(jù)的存儲過程。
以下是實(shí)際的創(chuàng)建語句:

--在測試用戶jingyu下創(chuàng)建測試表book2drop table book2 purge;create table book2(       
   bookId number(10) primary key,   
   name varchar2(20)         
); 

--創(chuàng)建序列  drop sequence book2_seq;    
create sequence book2_seq start with 1 increment by 1;    
  
--創(chuàng)建觸發(fā)器      create or replace trigger book2_trigger       
before insert on book2     
for each row       begin       select book2_seq.nextval into :new.bookId from dual;      
end ;  
/ 

--創(chuàng)建實(shí)現(xiàn)循環(huán)添加數(shù)據(jù)的存儲過程/*
--存儲過程中使用需要顯示賦權(quán)
grant execute on dbms_lock to jingyu;
*/create or replace procedure proc_insert_book2 isbegin
  loop
    insert into book2(name) values ('xx');    commit;
    dbms_lock.sleep(1);  end loop;end;
/

2.開始模擬該表不斷插入

由于我這里實(shí)際使用的是死循環(huán),所以只要開始執(zhí)行存儲過程,每秒都會向測試表插入1條測試數(shù)據(jù),直到手工停止。

--執(zhí)行該存儲過程exec proc_insert_book2;--查詢表的數(shù)量,確認(rèn)是每秒多一條數(shù)據(jù)select count(*) from book2;

3.進(jìn)行數(shù)據(jù)泵導(dǎo)出操作

確認(rèn)導(dǎo)出目錄,編寫expdp導(dǎo)出語句,最終將jingyu這個(gè)schema導(dǎo)出。實(shí)際命令如下:

--expdp 導(dǎo)出create or replace directory jy as '/opt/app/orabak/';
expdp jingyu/jingyu directory=jy dumpfile=jingyu.dmp schemas=jingyu

實(shí)際執(zhí)行導(dǎo)出的輸出如下:

[oracle@jyrac1 orabak]$ expdp jingyu/jingyu directory=jy dumpfile=jingyu.dmp schemas=jingyuExport: Release 11.2.0.4.0 - Production on Thu Jun 8 17:08:29 2017Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit ProductionWith the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,Data Mining and Real Application Testing optionsStarting "JINGYU"."SYS_EXPORT_SCHEMA_05":  jingyu/******** directory=jy dumpfile=jingyu.dmp schemas=jingyu 
Estimate in progress using BLOCKS method...Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATATotal estimation using BLOCKS method: 10.12 MBProcessing object type SCHEMA_EXPORT/USERProcessing object type SCHEMA_EXPORT/SYSTEM_GRANTProcessing object type SCHEMA_EXPORT/ROLE_GRANTProcessing object type SCHEMA_EXPORT/DEFAULT_ROLEProcessing object type SCHEMA_EXPORT/TABLESPACE_QUOTAProcessing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAProcessing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCEProcessing object type SCHEMA_EXPORT/TABLE/TABLEProcessing object type SCHEMA_EXPORT/TABLE/COMMENTProcessing object type SCHEMA_EXPORT/PROCEDURE/PROCEDUREProcessing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDUREProcessing object type SCHEMA_EXPORT/TABLE/INDEX/INDEXProcessing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINTProcessing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSProcessing object type SCHEMA_EXPORT/TABLE/TRIGGERProcessing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS. . exported "JINGYU"."T2"                               6.649 MB  100000 rows
. . exported "JINGYU"."SYS_EXPORT_SCHEMA_01"             142.0 KB    1195 rows
. . exported "JINGYU"."SYS_EXPORT_SCHEMA_02"             142.2 KB    1196 rows
. . exported "JINGYU"."SYS_EXPORT_SCHEMA_03"             142.6 KB    1198 rows
. . exported "JINGYU"."SYS_EXPORT_SCHEMA_04"             149.7 KB    1201 rows
. . exported "JINGYU"."T_OLD"                            160.8 KB   20000 rows
. . exported "JINGYU"."T"                                82.94 KB   10000 rows
. . exported "JINGYU"."T_NOLOG"                          51.53 KB    5998 rows
. . exported "JINGYU"."BOOK"                             5.421 KB       2 rows
. . exported "JINGYU"."BOOK2"                            6.734 KB     123 rows
. . exported "JINGYU"."EMP"                              8.562 KB      14 rows
. . exported "JINGYU"."T1"                               11.75 KB     100 rowsMaster table "JINGYU"."SYS_EXPORT_SCHEMA_05" successfully loaded/unloaded
******************************************************************************Dump file set for JINGYU.SYS_EXPORT_SCHEMA_05 is:
  /opt/app/orabak/jingyu.dmpJob "JINGYU"."SYS_EXPORT_SCHEMA_05" successfully completed at Thu Jun 8 17:10:26 2017 elapsed 0 00:01:36

4.進(jìn)行數(shù)據(jù)泵導(dǎo)入操作

將上一步的導(dǎo)出文件,導(dǎo)入到另一個(gè)新建的測試用戶jingyu2下。實(shí)際命令如下:

--創(chuàng)建測試用戶并賦予一定的權(quán)限create user jingyu2 identified by jingyu2 default tablespace dbs_d_jingyu;grant connect, resource to jingyu2;--impdp 導(dǎo)入到用戶jingyu2impdp jingyu/jingyu directory=jy dumpfile=jingyu.dmp REMAP_SCHEMA=jingyu:jingyu2

實(shí)際執(zhí)行導(dǎo)入的輸出如下:

[oracle@jyrac1 orabak]$ impdp jingyu/jingyu directory=jy dumpfile=jingyu.dmp REMAP_SCHEMA=jingyu:jingyu2Import: Release 11.2.0.4.0 - Production on Thu Jun 8 17:11:21 2017Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit ProductionWith the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,Data Mining and Real Application Testing optionsMaster table "JINGYU"."SYS_IMPORT_FULL_01" successfully loaded/unloadedStarting "JINGYU"."SYS_IMPORT_FULL_01":  jingyu/******** directory=jy dumpfile=jingyu.dmp REMAP_SCHEMA=jingyu:jingyu2 
Processing object type SCHEMA_EXPORT/USERORA-31684: Object type USER:"JINGYU2" already existsProcessing object type SCHEMA_EXPORT/SYSTEM_GRANTProcessing object type SCHEMA_EXPORT/ROLE_GRANTProcessing object type SCHEMA_EXPORT/DEFAULT_ROLEProcessing object type SCHEMA_EXPORT/TABLESPACE_QUOTAProcessing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAProcessing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCEProcessing object type SCHEMA_EXPORT/TABLE/TABLEProcessing object type SCHEMA_EXPORT/TABLE/TABLE_DATA. . imported "JINGYU2"."T2"                              6.649 MB  100000 rows
. . imported "JINGYU2"."SYS_EXPORT_SCHEMA_01"            142.0 KB    1195 rows
. . imported "JINGYU2"."SYS_EXPORT_SCHEMA_02"            142.2 KB    1196 rows
. . imported "JINGYU2"."SYS_EXPORT_SCHEMA_03"            142.6 KB    1198 rows
. . imported "JINGYU2"."SYS_EXPORT_SCHEMA_04"            149.7 KB    1201 rows
. . imported "JINGYU2"."T_OLD"                           160.8 KB   20000 rows
. . imported "JINGYU2"."T"                               82.94 KB   10000 rows
. . imported "JINGYU2"."T_NOLOG"                         51.53 KB    5998 rows
. . imported "JINGYU2"."BOOK"                            5.421 KB       2 rows
. . imported "JINGYU2"."BOOK2"                           6.734 KB     123 rows
. . imported "JINGYU2"."EMP"                             8.562 KB      14 rows
. . imported "JINGYU2"."T1"                              11.75 KB     100 rowsProcessing object type SCHEMA_EXPORT/TABLE/COMMENTProcessing object type SCHEMA_EXPORT/PROCEDURE/PROCEDUREProcessing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDUREORA-39082: Object type ALTER_PROCEDURE:"JINGYU2"."PRO_SELECT" created with compilation warningsORA-39082: Object type ALTER_PROCEDURE:"JINGYU2"."PROC_INSERT_BOOK2" created with compilation warningsProcessing object type SCHEMA_EXPORT/TABLE/INDEX/INDEXProcessing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINTProcessing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSProcessing object type SCHEMA_EXPORT/TABLE/TRIGGERProcessing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSJob "JINGYU"."SYS_IMPORT_FULL_01" completed with 3 error(s) at Thu Jun 8 17:11:52 2017 elapsed 0 00:00:26

導(dǎo)入完成,但存在一些警告,與本實(shí)驗(yàn)有關(guān)的只有"JINGYU2"."PROC_INSERT_BOOK2" 編輯警告需要處理,在下面的步驟中詳細(xì)說明。

5.問題現(xiàn)象重現(xiàn)并解決

問題現(xiàn)象重現(xiàn):
查詢到表最大的BOOKID大于序列的當(dāng)前值,具體情況如下:

SQL> select max(BOOKID) from book2;

MAX(BOOKID)
-----------        505SQL> select book2_seq.currval from dual;select book2_seq.currval from dual
                              *
ERROR at line 1:
ORA-08002: sequence BOOK2_SEQ.CURRVAL is not yet defined in this session


SQL> select book2_seq.nextval from dual;

   NEXTVAL
----------       341

導(dǎo)入的存儲過程存在編譯警告的問題,排查原因是權(quán)限問題,需要先處理下:

--執(zhí)行存儲過程報(bào)錯(cuò)對象無效
SQL> exec proc_insert_book2
BEGIN proc_insert_book2; END;

      *ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object JINGYU2.PROC_INSERT_BOOK2 is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

--重新編譯存儲過程依然有錯(cuò)誤
SQL> alter procedure proc_insert_book2 compile;

Warning: Procedure altered with compilation errors.

--顯示具體的錯(cuò)誤
SQL> show errors
Errors for PROCEDURE PROC_INSERT_BOOK2:

LINE/COL ERROR-------- -----------------------------------------------------------------6/5      PL/SQL: Statement ignored6/5      PLS-00201: identifier 'DBMS_LOCK' must be declared--根據(jù)錯(cuò)誤提示,賦權(quán)解決
SQL> show user
USER is "SYS"SQL> grant execute on dbms_lock to jingyu2;

Grant succeeded.

--再次編譯成功
SQL> alter procedure proc_insert_book2 compile;

Procedure altered.

編譯存儲過程成功后,執(zhí)行它模擬插入數(shù)據(jù),意料之中的會報(bào)錯(cuò):

SQL> exec proc_insert_book2
BEGIN proc_insert_book2; END;

*ERROR at line 1:
ORA-00001: unique constraint (JINGYU2.SYS_C0011351) violated
ORA-06512: at "JINGYU2.PROC_INSERT_BOOK2", line 4ORA-06512: at line 1--查詢測試表主鍵bookid的最大值
SQL> select max(bookid) from book2;

MAX(BOOKID)
-----------        505

重新創(chuàng)建序列,序列開始值設(shè)置為MAX(BOOKID)+1,再次執(zhí)行就可以正常插入了。
重新創(chuàng)建序列的語句如下:

--重新創(chuàng)建序列  drop sequence book2_seq;    
create sequence book2_seq start with 506 increment by 1;

至此,整個(gè)實(shí)驗(yàn)完成。

AlfredZhao?版權(quán)所有「從Oracle起航,領(lǐng)略精彩的IT技術(shù)?!?/p>

http://www.cnblogs.com/jyzhao/p/6964924.html