imp使用touser导入表空间问题

本文探讨了使用Oracle的IMP工具导入dmp文件时遇到的表空间问题。具体来说,即使导入脚本相同,在不同环境中导入同一文件时,表空间可能不同。文章详细解释了这一现象的原因在于IMP导入机制中,表空间的选择依赖于导出用户而非目标用户。

--今天在使用imp导入dmp文件的时候发现一个表空间的问题:
同一个文件在导入生产库的时候导入的表空间是 a_tbs (目标a用户的默认表空间)
在导入测试环境的时候导入的表空间是 users
使用的导入脚本也是完全相同的
所以这里就涉及了imp的导入机制

经过测试发现:
imp在使用touser进行制定用户导入的时候,导入哪个表空间不是由目标用户决定,
而是由导出用户fromuser决定的。

比如:
文件是由 s 用户导出,对应的表空间是 users
导入到用户 a, 对应的表空间是 a_tbs

导入的时候如果目标环境有users表空间,就算使用了touser参数,也会导入到users表空间下,
而如果目标环境没有users表空间,就会导入touser用户的默认表空间了。

<think> 我们正在讨论的是Oracle传统导入工具imp使用,特别是如何指定导入表空间。 用户的问题:我想了解在使用imp进行导入操作时如何指定导入表空间?请问imp导入数据库时指定导入表空间的方法 根据之前提供的引用和知识,我们可以总结如下: 引用[2]和引用[3]中提到,使用imp导入时可以指定表空间。但需要注意的是,传统的imp工具并没有直接提供一个参数来将对象导入到指定的表空间。然而,我们可以通过一些技巧来实现。 方法一:在导入前在目标数据库中创建与源库相同名称的表空间,或者如果要将对象导入到不同的表空间,可以在目标库中创建新的表空间,然后使用以下技巧: 1. 使用`imp`命令的`TABLESPACES`参数:这个参数实际上在imp中并不存在(注意:impdp中才有remap_tablespace)。在传统imp中,我们无法在命令行直接指定将对象导入到哪个表空间。但是,我们可以通过以下方式间接实现: 引用[3]中提到的命令: imp username/password file=’e:\***.dbf’ tablespaces=tbs fromuser=sourcename touser=targetname log=’e:\a.txt’ 然而,需要注意的是,传统imp的`tablespaces`参数并不是用来重定向表空间的,而是用来指定导入哪些表空间的对象(即只导入这些表空间中的对象)。因此,这个参数并不能实现将对象导入到指定表空间的功能。 方法二:通过修改导出文件(不推荐,因为二进制文件难以修改)或者使用导入时的重映射技巧。 方法三:在目标库中预先创建好需要导入表空间(名称可以与源库不同),然后使用以下步骤: 步骤1:从源库导出数据(使用exp)。 步骤2:在目标库创建需要的表空间(例如,我们想要导入表空间名为NEW_TBS)。 步骤3:在目标库创建要导入的用户,并将该用户的默认表空间设置为NEW_TBS。 步骤4:导入使用`fromuser`和`touser`参数,并且设置`ignore=y`(忽略创建错误,因为表结构可能已经存在,但我们希望数据插入到新的表空间)。 但是,这种方法要求重新创建用户,并将用户的默认表空间设置为目标表空间,这样在导入时创建的对象就会使用新的表空间。 然而,如果导出文件中包含表空间信息,导入时仍然会尝试在原来的表空间中创建对象。因此,我们需要在目标库中创建一个和源库相同名称的表空间,或者使用重映射。 但在传统imp中,没有重映射表空间的功能。因此,我们只能采用以下两种方式之一: 1. 在目标库中创建和源库相同名称的表空间(如果源库的表空间名称为TBS1,那么目标库也要有TBS1),这样导入就会成功。 2. 如果我们不想使用相同的表空间名称,那么我们可以: a) 先导入元数据(只导入结构),使用参数`rows=n`,然后手动修改创建脚本,将表空间名称改为新的表空间,然后再导入数据。 b) 或者,在导入之前,修改导出文件(不推荐,因为二进制文件难以修改)。 引用[4]中提到: 基本思路都是先从USER1导出表结构(DMP或者SQL脚本),然后在USER2用户下创建空的数据库表(如果是DMP,则参见方法1;如果是SQL脚本,则稍作修改后以USER2用户执行即可),再将包括数据的DMP导入,注意要设IGNORE=Y,并指定FROMUSER和TOUSER。 所以,我们可以这样做: 步骤1:导出时只导出表结构(使用exp的rows=n参数)。 步骤2:在目标库中,创建新用户并将该用户的默认表空间设置为目标表空间(比如NEW_TBS)。 步骤3:在目标库中执行步骤1中导出的结构脚本(如果是DMP文件,则先导入结构,使用imp的indexfile参数将表结构导出为脚本,然后修改脚本中的表空间名称,再运行脚本创建)。 步骤4:导入数据,使用`imp`命令,并设置`ignore=y`(因为表已经存在,所以会跳过创建,只导入数据),同时指定`fromuser`和`touser`。 这样,数据就会导入到已经创建好的表中,而这些表位于目标表空间。 但是,这种方法对于大型数据库来说比较繁琐。 另外,引用[5]中使用了ignore=y参数,可以忽略创建错误。 总结:传统imp工具没有直接重映射表空间的功能。所以,我们通常采用以下两种方法: 方法A(推荐):在目标库中创建与源库相同名称的表空间,然后导入。这样对象就会创建在相同名称的表空间中。 方法B:如果必须将对象导入到不同的表空间,则: 1. 在目标库中创建新的表空间(例如NEW_TBS)。 2. 创建用户,并将其默认表空间设置为NEW_TBS。 3. 导入数据时,使用`fromuser`和`touser`将对象导入到新用户,并设置`ignore=y`(前提是已经在新用户下创建了表结构,且表结构是在NEW_TBS表空间中创建的)。 注意:方法B中,表结构需要提前创建(通过导出结构并修改表空间后创建),然后再导入数据。 由于问题中用户希望指定导入表空间,那么我们可以采用方法A(如果能够控制源库和目标库的表空间名称)或者方法B(如果必须使用不同的表空间名称)。 但是,请注意,方法B需要额外的步骤来创建表结构。 因此,回答如下: 在Oracle传统导入工具imp中,没有直接参数(如数据泵的remap_tablespace)来重映射表空间。但可以通过以下两种方式实现将对象导入到指定表空间: 1. **同名表空间法(推荐)**: 在目标数据库中创建与源库相同名称的表空间(确保大小写一致),然后执行导入命令。这样,导入时对象会自动创建在同名表空间中。 例如,如果源库中对象在表空间`USERS`中,则在目标库创建`USERS`表空间,然后导入: ```bash imp system/password file=export.dmp full=y ``` 2. **预创建结构法**: 如果希望将对象导入到不同名称的表空间(如`NEW_TBS`),则需: - 在目标库创建目标表空间`NEW_TBS` - 创建用户并指定默认表空间为`NEW_TBS` - 从源库导出表结构(不包含数据): ```bash exp system/password file=struct.dmp rows=n ``` - 在目标库中导入结构(此时表会创建在用户的默认表空间`NEW_TBS`中): ```bash imp system/password file=struct.dmp fromuser=source_user touser=target_user ignore=y ``` - 导入数据(使用完整的数据导出文件,并设置`ignore=y`以跳过表创建错误): ```bash imp system/password file=data.dmp fromuser=source_user touser=target_user ignore=y ``` 注意:预创建结构法需要两次导入操作(先结构,后数据),且需确保表结构在目标库中正确创建在目标表空间。 另外,如果使用Oracle数据泵工具(impdp),则可以直接使用`remap_tablespace`参数实现表空间重定向,更简便: ```bash impdp system/password directory=dpdump_dir dumpfile=export.dmp remap_tablespace=OLD_TBS:NEW_TBS ``` 因此,如果条件允许,建议使用数据泵工具代替传统imp。 参考引用:[^2][^3][^4] 生成相关问题: 1. 使用imp导入时如何忽略表已存在的错误? 2. 如何将Oracle数据库从传统exp/imp迁移到数据泵(expdp/impdp)? 3. 使用数据泵导入时如何重映射表空间? </think> ### Oracle imp 工具指定导入表空间的方法 在 Oracle 传统导入工具 `imp` 中,**没有直接参数**(如数据泵的 `REMAP_TABLESPACE`)实现表空间重定向。但可通过以下两种方法实现: #### 方法一:同名表空间法(推荐) 1. **在目标库创建同名表空间** 确保目标库存在与源库**相同名称的表空间**(如 `RXTA`): ```sql CREATE TABLESPACE RXTA DATAFILE '/path/to/rxta01.dbf' SIZE 1G AUTOEXTEND ON; ``` 2. **执行导入命令** ```bash imp system/password@hostname file=export.dmp full=y ignore=y ``` - 对象将自动创建在同名表空间 `RXTA` 中 - `ignore=y` 忽略已存在对象错误[^4][^5] #### 方法二:用户默认表空间重定向 1. **在目标库创建新表空间** ```sql CREATE TABLESPACE NEW_TBS DATAFILE '/path/to/new_tbs01.dbf' SIZE 2G; ``` 2. **创建用户并指定默认表空间** ```sql CREATE USER target_user IDENTIFIED BY password DEFAULT TABLESPACE NEW_TBS; GRANT DBA TO target_user; -- 根据需要授权 ``` 3. **导入时重定向用户** ```bash imp system/password@hostname file=export.dmp fromuser=source_user touser=target_user ignore=y ``` - 所有对象将创建在 `target_user` 的默认表空间 `NEW_TBS` 中[^3][^4] #### ⚠️ 注意事项 1. **表空间必须预先存在** 目标表空间需提前创建且空间充足,否则报错: ```bash ORA-00959: tablespace 'XXX' does not exist ``` 2. **索引表空间问题** 索引可能仍使用表空间名称,需额外处理: ```sql ALTER INDEX index_name REBUILD TABLESPACE NEW_TBS; ``` 3. **LOB字段特殊处理** 包含 LOB 列的表需单独修改: ```sql ALTER TABLE table_name MOVE LOB(lob_column) STORE AS (TABLESPACE NEW_TBS); ``` 4. **建议迁移到数据泵** 现代 Oracle 版本推荐使用 `impdp`,支持直接重定向: ```bash impdp system/password DIRECTORY=dpump_dir DUMPFILE=export.dmp REMAP_TABLESPACE=OLD_TBS:NEW_TBS ``` > **关键区别**: > - 传统 `imp` 依赖表空间名称或用户默认设置 > - 数据泵 `impdp` 支持直接重映射(`REMAP_TABLESPACE`)[^1][^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值