Oracle 11G 的导入导出工具 exp 和 imp 是数据库管理员进行数据迁移、备份和恢复的重要工具。然而,在11G R2 版本中,由于一个新特性,空表在没有数据的情况下不会分配 segment,导致无法通过 exp 导出。这个问题可以通过以下几种方法解决:
1. **插入并回滚数据**:向空表中插入一行数据,然后执行 rollback 操作,这样就会为表分配 segment,使得在导出时能够包含这个空表。这是对单个表的临时解决方案。
2. **修改 deferred_segment_creation 参数**:默认情况下,这个参数的值为 TRUE,意味着只有在表有数据时才会分配 segment。将其更改为 FALSE,将使所有表(无论是否为空)在创建时就分配 segment。执行 `alter system set deferred_segment_creation=false scope=both;` 这个 SQL 语句来修改。但是请注意,这个设置对已经存在的空表无效,只会影响后续新建的表。
3. **手动分配 extent**:使用 SQL 查询 `select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0;` 可以找到所有空表,并生成一条 alter 语句来为它们分配 extent。执行这些语句后,空表就可以在导出时被包括在内了。
4. **使用 expdp 和 impdp**:从 Oracle 10g 开始,引入了新的数据泵工具 expdp 和 impdp,它们提供了更丰富的导出和导入选项。使用这些工具,即使空表也能被导出。例如:
- 创建逻辑目录:`create directory db_bak as 'd:\test\dump';`
- 授予目录操作权限:`grant read,write on directory db_bak to system;`
- 导出数据示例:
- 按用户导出:`expdp system/manager@orcl schemas=system dumpfile=expdp.dmp DIRECTORY=db_bak`
- 并行导出:`expdp system/manager@orcl directory=db_bak dumpfile=system3.dmp parallel=40 job_name=system3`
- 按表名导出:`expdp system/manager@orcl TABLES=emp,dept dumpfile=expdp.dmp DIRECTORY=db_bak`
- 按查询条件导出:`expdp system/manager@orcl directory=db_bak dumpfile=expdp.dmp Tables=emp query='WHERE deptno=20'`
- 按表空间导出:`expdp system/manager DIRECTORY=db_bak DUMPFILE=tablespace.dmp TABLESPACES=temp,example`
- 导出整个数据库:`expdp system/mtmadmin DIRECTORY=db_bak DUMPFILE=full.dmp FULL=y`
- 导入数据示例:
- 导入到指定用户:`impdp system/manager DIRECTORY=db_bak DUMPFILE=expdp.dmp SCHEMAS=system`
- 更改表的所有者:`impdp system/manager DIRECTORY=db_bak DUMPFILE=expdp.dmp TABLES=system.dept REMAP_SCHEMA=system:system`
- 导入表空间:`impdp system/manager DIRECTORY=db_bak DUMPFILE=tablespace.dmp TABLESPACES=example`
- 导入整个数据库:`impdb system/mtmadmin DIRECTORY=db_bak DUMPFILE=full.dmp FULL=y`
- 追加数据:`impdp system/manager DIRECTORY=db_bak DUMPFILE=expdp.dmp`
通过以上方法,可以有效地解决 Oracle 11G R2 中空表无法通过 exp 导出的问题。在处理大量数据时,使用 expdp 和 impdp 工具不仅可以导出空表,还提供了更多的控制选项,比如并行导出、按条件过滤数据等,提高了数据迁移的效率和灵活性。