zoukankan      html  css  js  c++  java
  • 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的语句是很特殊,中间有timestampoid信息。而且与原来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));"

       

       

    看来,timestampoid的确是DUMP文件的一部分。也就是说,Oracleimp type类型的时候,要将原有的timestampoid连带的转移到新的数据环境中。

       

    那么,如果我们是转移到其他数据环境下,是否有问题呢?答案是否定的,经过实验,只要不是相同数据库,imp操作都是正常的。

       

    问题的关键在于oid,从格式上看,OID是一个类似于GUID的字符串。按照GUID生成规则,GUID是不可能重复的。笔者猜测在Oracle内部,要求type类型不管schema归属,每一个type都必须有一个唯一的OID编号。当我们在一个数据库中强制插入两个相同oidtype时,系统自然报错。

       

    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导出导入问题。

    转载自:http://blog.itpub.net/17203031/viewspace-732089/

  • 相关阅读:
    hdu 1998 奇数阶魔方(找规律+模拟)
    巧用百度Site App新组件为企业官网打造移动站
    POJ 1276 Cash Machine
    Unity3D中使用MiniJson解析json的例子
    设计模式读书笔记-----单例模式
    android 常用资料
    Objective-C之run loop详解
    icon 图标下载
    揭开Html 标签的面纱,忘不了的html .
    12157
  • 原文地址:https://www.cnblogs.com/skiing886/p/10011395.html
Copyright © 2011-2022 走看看