Oracle 19c入门学习教程,从入门到精通,Oracle 数据导出和导入 — 语法知识点与使用方法详解(18)

Oracle 数据导出和导入 --- 语法知识点与使用方法详解


一、环境准备(Oracle 安装与目录配置)

前提 :Oracle Database 已安装(如第16章所述)。
本章工具 expdp / impdp(Data Pump)和 sqlldr(SQL*Loader)随 Oracle 自动安装,无需额外安装。

1. 创建操作系统目录(用于存储导出/导入文件)

bash 复制代码
# Linux 示例
mkdir -p /u01/app/oracle/dump

# Windows 示例
mkdir D:\oracle\dump

2. 在 Oracle 中创建 DIRECTORY 对象(必须!)

Data Pump 要求使用 Oracle DIRECTORY 对象,不能直接使用 OS 路径。

sql 复制代码
-- 以 sys 或具有 DBA 权限用户登录
CREATE DIRECTORY DATA_PUMP_DIR AS '/u01/app/oracle/dump';
-- Windows: CREATE DIRECTORY DATA_PUMP_DIR AS 'D:\oracle\dump';

-- 授权给目标用户(如 test_user)
GRANT READ, WRITE ON DIRECTORY DATA_PUMP_DIR TO test_user;

✅ 验证:

sql 复制代码
SELECT * FROM dba_directories WHERE directory_name = 'DATA_PUMP_DIR';

二、EXPDP(Data Pump Export)详解

1. EXPDP 概述

  • 替代旧版 exp 工具,性能更高、功能更强。
  • 支持并行、压缩、加密、过滤、重映射等。
  • 导出文件为 .dmp(二进制) + 可选日志文件(.log)。

2. 执行 EXPDP 命令(操作系统命令行)

bash 复制代码
expdp username/password@tns_alias DIRECTORY=dir_name DUMPFILE=file.dmp LOGFILE=file.log

⚠️ 注意:DIRECTORY 必须是 Oracle 中已定义的 DIRECTORY 对象名(非 OS 路径)。


3. EXPDP 核心参数详解(带案例)

(1) 全库导出(Full Database)
bash 复制代码
expdp system/password FULL=Y \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=full_db_%U.dmp \
  LOGFILE=full_db.log \
  PARALLEL=4
  • FULL=Y:导出整个数据库(需 DBA 权限)
  • %U:自动分卷(如 full_db_01.dmp, full_db_02.dmp)
  • PARALLEL=4:启用 4 个并行进程加速

(2) 按用户导出(Schema Mode)
bash 复制代码
expdp test_user/test123 \
  SCHEMAS=test_user \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=test_user.dmp \
  LOGFILE=test_user_export.log \
  COMPRESSION=ALL
  • SCHEMAS=test_user:仅导出该用户所有对象
  • COMPRESSION=ALL:压缩元数据和数据(11g+)

(3) 按表导出(Table Mode)
bash 复制代码
expdp test_user/test123 \
  TABLES=employees,departments \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=emp_dept.dmp \
  QUERY=employees:"WHERE salary > 5000" \
  LOGFILE=table_export.log
  • TABLES=...:指定表列表
  • QUERY=...:对表加 WHERE 条件(仅导出满足条件的数据)

💡 注意:QUERY 中的双引号在 Linux 需转义或用单引号包裹。


(4) 仅导出元数据(No Data)
bash 复制代码
expdp test_user/test123 \
  SCHEMAS=test_user \
  CONTENT=METADATA_ONLY \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=schema_meta.dmp
  • CONTENT=METADATA_ONLY:只导出表结构、索引、约束等,不导数据

(5) 排除特定对象
bash 复制代码
expdp test_user/test123 \
  SCHEMAS=test_user \
  EXCLUDE=INDEX,STATISTICS,CONSTRAINT \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=no_index.dmp
  • EXCLUDE=...:排除索引、统计信息、约束等

三、IMPDP(Data Pump Import)详解

1. IMPDP 概述

  • 与 EXPDP 配套,用于导入 .dmp 文件。
  • 支持重命名、跳过错误、转换字符集等。

2. 执行 IMPDP 命令

bash 复制代码
impdp username/password DIRECTORY=dir_name DUMPFILE=file.dmp LOGFILE=import.log

3. IMPDP 核心参数详解(带案例)

(1) 全库导入(需谨慎!)
bash 复制代码
impdp system/password FULL=Y \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=full_db.dmp \
  LOGFILE=full_import.log

⚠️ 通常用于新库重建,生产环境慎用。


(2) 导入到不同用户(Remap Schema)
bash 复制代码
impdp system/password \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=test_user.dmp \
  REMAP_SCHEMA=test_user:prod_user \
  LOGFILE=remap_import.log
  • REMAP_SCHEMA=源:目标:将 test_user 的对象导入到 prod_user 下

(3) 表存在时跳过或替换
bash 复制代码
impdp test_user/test123 \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=emp_dept.dmp \
  TABLE_EXISTS_ACTION=REPLACE \
  LOGFILE=replace_import.log
  • TABLE_EXISTS_ACTION 取值:
    • SKIP(默认):跳过已存在表
    • APPEND:追加数据
    • TRUNCATE:清空表后插入
    • REPLACE:删除表重建

(4) 仅导入数据(跳过元数据)
bash 复制代码
impdp test_user/test123 \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=data_only.dmp \
  CONTENT=DATA_ONLY \
  LOGFILE=data_import.log

(5) 并行导入(加速大库)
bash 复制代码
impdp system/password \
  FULL=Y \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=full_db_%U.dmp \
  PARALLEL=4 \
  LOGFILE=parallel_import.log

四、SQL*Loader 工具详解

1. SQL*Loader 概述

  • 用于从外部平面文件(如 CSV、TXT)高速加载数据到 Oracle 表。
  • 比 INSERT 快 10~100 倍(尤其适合批量初始化)。
  • 需要控制文件(.ctl)定义数据格式。

2. 准备数据文件(data.csv)

csv 复制代码
101,John Doe,IT,7500
102,Jane Smith,HR,6500
103,Bob Johnson,SALES,5500

3. 创建目标表

sql 复制代码
CREATE TABLE emp_load (
  emp_id    NUMBER,
  emp_name  VARCHAR2(50),
  dept      VARCHAR2(30),
  salary    NUMBER
);

4. 编写控制文件(emp_load.ctl)

ctl 复制代码
LOAD DATA
INFILE 'data.csv'
APPEND
INTO TABLE emp_load
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
  emp_id,
  emp_name,
  dept,
  salary
)
  • INFILE:数据文件路径(相对或绝对)
  • APPEND:追加模式(其他:INSERT / REPLACE / TRUNCATE)
  • FIELDS TERMINATED BY ',':字段以逗号分隔
  • TRAILING NULLCOLS:允许末尾字段为空

5. 执行 SQL*Loader

bash 复制代码
# 命令格式
sqlldr userid=test_user/test123 control=emp_load.ctl log=load.log bad=bad_records.bad

# 示例
sqlldr test_user/test123 control=/home/oracle/emp_load.ctl
  • bad=...:记录无法加载的行(如格式错误)
  • log=...:生成执行日志

✅ 成功后,emp_load 表将包含 3 行数据。


6. 高级功能:日期/函数处理

假设 CSV 包含日期:

csv 复制代码
104,Alice Brown,2025-01-15,8000

控制文件修改:

ctl 复制代码
LOAD DATA
INFILE 'data_with_date.csv'
APPEND
INTO TABLE emp_hire
FIELDS TERMINATED BY ','
(
  emp_id,
  emp_name,
  hire_date DATE "YYYY-MM-DD",
  salary
)

五、综合性案例

场景1:跨平台迁移用户数据(开发 → 生产)

步骤1:在开发库导出 test_dev 用户
bash 复制代码
expdp test_dev/dev123 \
  SCHEMAS=test_dev \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=migration.dmp \
  COMPRESSION=ALL \
  LOGFILE=export_migration.log
步骤2:将 .dmp 文件复制到生产服务器
bash 复制代码
scp migration.dmp prod_server:/u01/app/oracle/dump/
步骤3:在生产库创建目标用户并授权
sql 复制代码
CREATE USER test_prod IDENTIFIED BY prod456;
GRANT CONNECT, RESOURCE TO test_prod;
CREATE DIRECTORY DATA_PUMP_DIR AS '/u01/app/oracle/dump';
GRANT READ, WRITE ON DIRECTORY DATA_PUMP_DIR TO test_prod;
步骤4:导入并重映射
bash 复制代码
impdp system/prod_sys_password \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=migration.dmp \
  REMAP_SCHEMA=test_dev:test_prod \
  TABLE_EXISTS_ACTION=SKIP \
  LOGFILE=import_prod.log

✅ 结果:开发库的 test_dev 对象完整迁移到生产库 test_prod 用户下。


场景2:每日从 CSV 加载销售数据(自动化脚本)

目录结构:
复制代码
/scripts/load_sales.sh
/data/sales_20260118.csv
/ctl/sales.ctl
sales.ctl 内容:
ctl 复制代码
LOAD DATA
INFILE '/data/sales_*.csv'
APPEND
INTO TABLE daily_sales
FIELDS TERMINATED BY '|'
(
  sale_id,
  product_id,
  amount,
  sale_date DATE "YYYYMMDD"
)
load_sales.sh 脚本:
bash 复制代码
#!/bin/bash
DATE=$(date +%Y%m%d)
LOG="/logs/sqlldr_$DATE.log"

sqlldr test_user/test123 \
  control=/ctl/sales.ctl \
  log=$LOG \
  bad=/bad/sales_$DATE.bad

# 检查是否成功
if grep -q "successfully completed" $LOG; then
  echo "Load successful" >> /logs/status.log
  # 移动已处理文件
  mv /data/sales_$DATE.csv /archive/
else
  echo "Load failed!" >> /logs/error.log
  mail -s "SQL*Loader Failed" admin@example.com < $LOG
fi
定时任务(crontab):
cron 复制代码
# 每天凌晨2点执行
0 2 * * * /scripts/load_sales.sh

六、常见问题与最佳实践

问题 解决方案
ORA-39002: invalid operation 检查 DIRECTORY 是否存在且授权
EXPDP 卡住 检查磁盘空间、权限、并行度是否过高
IMPDP 报表已存在 使用 TABLE_EXISTS_ACTION=REPLACE
SQL*Loader 乱码 确保数据文件编码与数据库一致(如 UTF8)
大文件导出慢 启用 PARALLEL + COMPRESSION=ALL

最佳实践:

  1. 定期测试恢复:导出后立即做一次导入验证。
  2. 保留多个版本 :按日期命名 dump 文件(如 emp_20260118.dmp)。
  3. 监控日志 :分析 .log 文件中的警告和错误。
  4. 权限最小化:不要用 SYSTEM 导普通用户数据,用对应 schema 用户。
  5. 结合 RMAN:Data Pump 用于逻辑备份,RMAN 用于物理备份,二者互补。

通过掌握 expdp/impdpsqlldr,可高效完成 Oracle 数据迁移、初始化、灾备恢复等关键任务,是 DBA 和开发人员必备技能。

相关推荐
木辰風5 小时前
PLSQL自定义自动替换(AutoReplace)
java·数据库·sql
无限码力5 小时前
华为OD技术面真题 - 数据库MySQL - 3
数据库·mysql·华为od·八股文·华为od技术面八股文
heartbeat..5 小时前
Redis 中的锁:核心实现、类型与最佳实践
java·数据库·redis·缓存·并发
Prince-Peng5 小时前
技术架构系列 - 详解Redis
数据结构·数据库·redis·分布式·缓存·中间件·架构
虾说羊5 小时前
redis中的哨兵机制
数据库·redis·缓存
_F_y5 小时前
MySQL视图
数据库·mysql
lxl13075 小时前
学习C++(5)运算符重载+赋值运算符重载
学习
2301_790300965 小时前
Python单元测试(unittest)实战指南
jvm·数据库·python
九章-6 小时前
一库平替,融合致胜:国产数据库的“统型”范式革命
数据库·融合数据库
AutumnorLiuu6 小时前
C++并发编程学习(一)——线程基础
开发语言·c++·学习