IMP同庫Type物件匯入報錯ORA-02304
Type是我們經常使用的資料庫物件結構。我們在實際中,可以單獨定義type型別,之後在PL/SQL程式碼或者資料表中使用。
在一個偶然的機會讓筆者發現使用Type型別在資料exp/imp中的麻煩。當我們使用exp/imp工具進行同資料庫例項(Instance)不同Schema之間資料複製時,如果Schema中有type型別,就會出現問題錯誤。
具體我們還是透過一系列的實驗進行證明。
1、實驗環境準備
我們使用10gR2作為實驗資料庫。
SQL> conn scott/tiger@ots;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as scott
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
我們首先將scott使用者schema的所有物件匯出。注意,當前scott下存在一些資料type物件。
SQL> select type_name, type_oid, typecode from user_types;
TYPE_NAME TYPE_OID TYPECODE
------------------------------ -------------------------------- ------------------------------
CUST_ADDRESS_TYPE_NEW 0239FC5ABD78464D8D6C4D7085E2F549 OBJECT
T_REC_TEST 428A1B3C7E1E4A3CB2063B93623693EA OBJECT
T_REC_TABLE D9AFD3FAE0A54964B1684CA28C69CEED COLLECTION
T_TYP 8E294AB7CC28493A94FF82791A376379 OBJECT
N_TYP 338172B836854BAB8C26D4C27B5908F1 OBJECT
在Oracle中,每一個type都會分配出唯一的oid編號,作為一種內部標誌。下面,我們使用exp工具將scott使用者物件匯出。
D:\>exp scott/tiger@ots file=scott_20120606.dmp indexes=y rows=y compress=y cons
traints=y wner=scott
Export: Release 10.2.0.1.0 - Production on 星期三 6月 6 17:22:16 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
連線到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
已匯出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集
即將匯出指定的使用者...
. 正在匯出 pre-schema 過程物件和操作
. 正在匯出使用者 SCOTT 的外部函式庫名
. 匯出 PUBLIC 型別同義詞
. 正在匯出專用型別同義詞
. 正在匯出使用者 SCOTT 的物件型別定義
(篇幅原因,部分省略……)
成功終止匯出, 沒有出現警告。
D:\>
之後,我們建立同資料庫使用者scottback。
SQL> create user scottback identified by scottback;
User created
SQL> grant resource to scottback;
Grant succeeded
SQL> grant connect to scottback;
Grant succeeded
SQL> grant exp_full_database to scottback;
Grant succeeded
SQL> grant imp_full_database to scottback;
Grant succeeded
2、資料匯入
當我們試圖將資料匯入到相同資料庫時,出現報錯。
D:\>imp scottback/scottback@ots file=scott_20120606.dmp indexes=y rows=y constra
ints=y ignore=y fromuser=scott touser=scottback
Import: Release 10.2.0.1.0 - Production on 星期三 6月 6 17:34:21 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
連線到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
經由常規路徑由 EXPORT:V10.02.01 建立的匯出檔案
警告: 這些物件由 SCOTT 匯出, 而不是當前使用者
已經完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的匯入
IMP-00017: 由於 ORACLE 錯誤 2304, 以下語句失敗:
"CREATE TYPE "T_REC_TEST" TIMESTAMP '2010-12-21:18:17:30' OID '428A1B3C7E1E4"
"A3CB2063B93623693EA' as object("
"id number);"
""
""
IMP-00003: 遇到 ORACLE 錯誤 2304
ORA-02304: 無效的物件識別符號文字
IMP-00017: 由於 ORACLE 錯誤 2304, 以下語句失敗:
"CREATE TYPE "T_REC_TABLE" TIMESTAMP '2010-12-21:18:17:33' OID 'D9AFD3FAE0A5"
"4964B1684CA28C69CEED' as table of t_rec_test;"
""
""
IMP-00003: 遇到 ORACLE 錯誤 2304
ORA-02304: 無效的物件識別符號文字
IMP-00017: 由於 ORACLE 錯誤 2304, 以下語句失敗:
"CREATE TYPE "T_TYP" TIMESTAMP '2012-03-07:10:47:03' OID '8E294AB7CC28493A94"
"FF82791A376379' as object (id number);"
""
""
IMP-00003: 遇到 ORACLE 錯誤 2304
ORA-02304: 無效的物件識別符號文字
IMP-00017: 由於 ORACLE 錯誤 2304, 以下語句失敗:
"CREATE TYPE "N_TYP" TIMESTAMP '2012-03-07:11:03:01' OID '338172B836854BAB8C"
"26D4C27B5908F1' as object (t_id number,t_name varchar2(10),t_addr varchar"
"2(20));"
""
""
IMP-00003: 遇到 ORACLE 錯誤 2304
ORA-02304: 無效的物件識別符號文字
IMP-00017: 由於 ORACLE 錯誤 2304, 以下語句失敗:
"CREATE TYPE "CUST_ADDRESS_TYPE_NEW" TIMESTAMP '2012-05-23:16:15:03' OID '02"
"39FC5ABD78464D8D6C4D7085E2F549' as object"
"(street_address varchar2"
"(40),"
"postal_code varchar2(10)"
",city varchar2(30)"
",state_province varchar2(10)"
",country_id char(2)"
");"
""
""
IMP-00003: 遇到 ORACLE 錯誤 2304
ORA-02304: 無效的物件識別符號文字
(篇幅原因,部分省略…..)
ORA-02270: 此列列表的唯一或主鍵不匹配
即將啟用約束條件...
成功終止匯入, 但出現警告。
從日誌資訊上,我們看到在建立type型別變數的時候,Oracle報錯2304。利用oerr工具,我們可以檢查錯誤資訊。
[oracle@bspdev ~]$ oerr ora 2304
02304, 00000, "invalid object identifier literal"
// *Cause: An attempt was made to enter an object identifier literal for
// CREATE TYPE that is either:
// - not a string of 32 hexadecimal characters
// - an object identifier that already identifies an existing
// object
// - an object identifier different from the original object
// identifier already assigned to the type
// *Action: Do not specify the object identifier clause or specify a 32
// hexadecimal-character object identifier literal that is unique
// or identical to the originally assigned object identifier. Then
// retry the operation.
從字面的情況看,是建立type的命令語句出現錯誤。從指令碼的資訊上,的確顯示的script中建立type的語句是很特殊,中間有timestamp和oid資訊。而且與原來schema中的相對應。
那麼,這個特殊的語法結構是否是檔案中特有的呢?我們使用show引數,將dmp指令碼輸出。
D:\>imp scottback/scottback@ots file=scott_20120606.dmp indexes=y rows=y constra
ints=y ignore=y show=y fromuser=scott touser=scottback log=imp.log
連線到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
經由常規路徑由 EXPORT:V10.02.01 建立的匯出檔案
警告: 這些物件由 SCOTT 匯出, 而不是當前使用者
已經完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的匯入
"CREATE TYPE "T_REC_TEST" TIMESTAMP '2010-12-21:18:17:30' OID '428A1B3C7E1E4"
"A3CB2063B93623693EA' as object("
"id number);"
""
"CREATE TYPE "T_REC_TABLE" TIMESTAMP '2010-12-21:18:17:33' OID 'D9AFD3FAE0A5"
"4964B1684CA28C69CEED' as table of t_rec_test;"
""
"CREATE TYPE "T_TYP" TIMESTAMP '2012-03-07:10:47:03' OID '8E294AB7CC28493A94"
"FF82791A376379' as object (id number);"
""
"CREATE TYPE "N_TYP" TIMESTAMP '2012-03-07:11:03:01' OID '338172B836854BAB8C"
"26D4C27B5908F1' as object (t_id number,t_name varchar2(10),t_addr varchar"
"2(20));"
看來,timestamp和oid的確是DUMP檔案的一部分。也就是說,Oracle在imp type型別的時候,要將原有的timestamp和oid連帶的轉移到新的資料環境中。
那麼,如果我們是轉移到其他資料環境下,是否有問題呢?答案是否定的,經過實驗,只要不是相同資料庫,imp操作都是正常的。
問題的關鍵在於oid,從格式上看,OID是一個類似於GUID的字串。按照GUID生成規則,GUID是不可能重複的。筆者猜測在Oracle內部,要求type型別不管schema歸屬,每一個type都必須有一個唯一的OID編號。當我們在一個資料庫中強制插入兩個相同oid的type時,系統自然報錯。
在MOS中,筆者也找到了相應的依據。
[ID 1066139.6]
In brief, if the FROMUSER's object types already exist on the target instance, errors occur because the object identifiers (OIDs) of the TOUSER's object types already exist. Within a single database instance, object identifiers (OIDs) must be unique. As a result, the error causes Import will skip the creation of relational tables with columns of the pre-existing user defined type.
3、解決方法
綜合各方面的意見,關鍵問題在於匯出的type攜帶有唯一的oid資訊,並且需要匯入到同庫schema中。在使用exp/imp的情況下,我們是沒有什麼很好的方法。最直接的做法就是將資料庫中衝突的type和相關聯的物件刪除,這樣做不是一般場景可以支援的。
在MOS中提供了一些折中方法,其中一個是在imp之前,就手工的將type物件建立好。這樣最多在imp設定ignore=y的時候報錯物件重複。
--手工建立type
SQL> conn scottback/scottback@ots;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as scottback
SQL> create or replace type cust_address_type_new as object
2 (
3 street_address varchar2(40),
4 postal_code varchar2(10),
5 city varchar2(30),
6 state_province varchar2(10),
7 country_id char(2)
8 )
9 ;
10 /
Type created
SQL> create or replace type n_typ as object(t_id number, t_name varchar2(10), t_addr varchar2(20));
2 /
Type created
SQL>
SQL> create or replace type t_rec_test as object(id number);
2 /
Type created
SQL> create or replace type t_typ as object(id number);
2 /
Type created
SQL>
SQL> create or replace type t_rec_table as table of t_rec_test;
2 /
Type created
--匯入操作;
D:\>imp scottback/scottback@ots file=scott_20120606.dmp indexes=y rows=y constraints=y ignore=y fromuser=scott touser=scottback log=res.log
警告: 這些物件由 SCOTT 匯出, 而不是當前使用者
已經完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的匯入
IMP-00061: 警告: 物件型別 "SCOTTBACK"."T_REC_TEST" 已經以不同識別符號存在
"CREATE TYPE "T_REC_TEST" TIMESTAMP '2010-12-21:18:17:30' OID '428A1B3C7E1E4"
"A3CB2063B93623693EA' as object("
"id number);"
""
""
IMP-00061: 警告: 物件型別 "SCOTTBACK"."T_REC_TABLE" 已經以不同識別符號存在
"CREATE TYPE "T_REC_TABLE" TIMESTAMP '2010-12-21:18:17:33' OID 'D9AFD3FAE0A5"
"4964B1684CA28C69CEED' as table of t_rec_test;"
""
""
IMP-00061: 警告: 物件型別 "SCOTTBACK"."T_TYP" 已經以不同識別符號存在
"CREATE TYPE "T_TYP" TIMESTAMP '2012-03-07:10:47:03' OID '8E294AB7CC28493A94"
"FF82791A376379' as object (id number);"
""
""
IMP-00061: 警告: 物件型別 "SCOTTBACK"."N_TYP" 已經以不同識別符號存在
"CREATE TYPE "N_TYP" TIMESTAMP '2012-03-07:11:03:01' OID '338172B836854BAB8C"
"26D4C27B5908F1' as object (t_id number,t_name varchar2(10),t_addr varchar"
"2(20));"
""
""
IMP-00061: 警告: 物件型別 "SCOTTBACK"."CUST_ADDRESS_TYPE_NEW" 已經以不同識別符號存在
"CREATE TYPE "CUST_ADDRESS_TYPE_NEW" TIMESTAMP '2012-05-23:16:15:03' OID '02"
"39FC5ABD78464D8D6C4D7085E2F549' as object"
"(street_address varchar2"
"(40),"
"postal_code varchar2(10)"
",city varchar2(30)"
",state_province varchar2(10)"
",country_id char(2)"
");"
""
""
. . 正在匯入表 "A"匯入了 1 行
IMP-00063: 警告: 跳過表 "SCOTTBACK"."ADDRESS_TABLE", 因為無法建立物件型別 "SCOTTBACK"."CUST_ADDRESS_TYPE_NEW" 或它具有不同的識別符號
. . 正在匯入表 "B"匯入了 2 行
. . 正在匯入表 "BONUS"匯入了 0 行
. . 正在匯入表 "BO_TEST"匯入了 0 行
. . 正在匯入表 "CHAINED_ROWS"
注: 表包含 ROWID 列, 其值可能已廢棄匯入了 0 行
. . 正在匯入表 "CHILD"匯入了 0 行
. . 正在匯入表 "CURSOR"匯入了 3 行
IMP-00063: 警告: 跳過表 "SCOTTBACK"."CUSTOMER_ADDRESSES", 因為無法建立物件型別 "SCOTTBACK"."CUST_ADDRESS_TYPE_NEW" 或它具有不同的識別符號
這樣做的確可以避免報錯。但是後果也是存在的,如果這些匯入的type存在依賴物件。如資料表列、儲存過程程式碼依賴於type。雖然手工建立了原有type,但是這些物件也不會使用建立好的type物件。筆者猜測這就是oid的作用。
SQL> select name, type, DEPENDENCY_TYPE from user_dependencies where REFERENCED_NAME in (select type_name from user_types);
NAME TYPE DEPENDENCY_TYPE
------------------------------ ----------------- ---------------
CUSTOMER_ADDRESSES TABLE REF
ADDRESS_TABLE TABLE HARD
F_SPILE FUNCTION HARD
T_REC_TABLE TYPE HARD
F_SPILE FUNCTION HARD
N_T TABLE HARD
6 rows selected
4、結論
在使用type中,一定要注意可能引起的imp/exp匯出匯入問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-732089/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- IMP同庫Type物件匯入報錯ORA-02304(續)物件
- oracle匯入TYPE物件報錯ORA-02304Oracle物件
- ORACLE exp/imp匯入報錯IMP-00009&IMP-00028&IMP-00015Oracle
- exp/imp匯入匯出版本問題和ORA-6550報錯
- imp匯入檔案時報大量的imp-0008錯誤
- Oracle資料庫匯入匯出。imp匯入命令和exp匯出命令Oracle資料庫
- expdp 全庫匯入報錯總結
- 物件及資料存在時的資料匯入(imp)物件
- 【EXP/IMP】使用EXP /IMP工具“模糊”匯出和匯入
- 資料匯入匯出EXP/IMP
- exp/imp匯出匯入資料
- Oracle匯入(imp )與匯出(exp )Oracle
- ORACLE匯入匯出命令exp/impOracle
- imp匯入資料庫表時浮現ORA-01658錯誤資料庫
- oracle資料匯出匯入(exp/imp)Oracle
- Oracle 遠端匯出匯入 imp/expOracle
- exp/imp匯出匯入工具的使用
- mysqlimport匯入報錯的排查MySqlImport
- Oracle exp/imp匯出匯入工具的使用Oracle
- Oracle資料匯入匯出imp/exp命令Oracle
- oracle資料的匯入匯出imp/expOracle
- Windows DOS窗體下Oracle 資料庫的匯入匯出(IMP/EXP)命令WindowsOracle資料庫
- oracle imp匯入幾點小記Oracle
- imp exp 跨系統匯入案例
- Oracle資料匯入匯出imp/exp命令(轉)Oracle
- 【匯出匯入】匯出匯入 大物件物件
- Oracle資料庫備份與恢復之exp/imp(匯出與匯入裝庫與卸庫)Oracle資料庫
- PythonMySQLdb匯入libmysqlclient報錯PythonMySqlIBMclient
- imp工具匯入整個資料庫出現的問題資料庫
- oracle 10g asm資料庫imp匯入慢處理Oracle 10gASM資料庫
- imp 匯入遇到 FK (Foreign Key) 導致錯誤處理
- Mysql資料庫使用Navicat Mysql匯入sql檔案報錯MySql資料庫
- Oracle資料庫備份與恢復之一:exp/imp(匯出與匯入裝庫與卸庫)Oracle資料庫
- Oracle 資料庫備份與恢復總結-exp/imp (匯出與匯入裝庫與卸庫)Oracle資料庫
- oracle 10.1.0.2匯入IMP-00017Oracle
- mysql匯入報錯怎麼解決?MySql
- magento sql 4G 匯入報錯SQL
- 用EXP/IMP從高版本資料庫匯出至低版本資料庫匯入實驗資料庫