最简方式是用EXPDP配合TABLES参数导出表,需确保DATA_PUMP_DIR权限;TABLES格式为schema.table_name,多表逗号分隔,大小写表名需双引号;PL/SQL仅用于生成命令而非执行;关键参数包括CONTENT、EXCLUDE、VERSION;禁用手写UTL_FILE导出。
导出特定表的最简方式:用 EXPDP 配合 TABLES 参数
直接用 oracle 数据泵(expdp)导出单张或几张表,比在 pl/sql 里拼脚本更可靠、更高效。pl/sql 本身不生成物理备份文件,它只能帮你动态构造 expdp 命令字符串——最终还得靠操作系统执行。所以第一步要确认你有 data_pump_dir 目录对象且写入权限。
常见错误现象:ORA-39002: invalid operation 或 ORA-39070: Unable to open the log file,基本都是目录权限或路径不存在导致的。
-
EXPDP必须在数据库服务器本地或配置了可信连接的客户端运行,不能通过普通 SQL*Plus 远程触发 - 命令中
TABLES的格式是schema.table_name,多个用英文逗号分隔,不能带空格:scott.emp,scott.dept - 如果表名含大小写或特殊字符,必须用双引号包裹:
"MyTable",且整个参数需加单引号避免 shell 解析错误
用 PL/SQL 动态生成 EXPDP 命令字符串的实用写法
适用于需要按条件(如表名前缀、最后 DDL 时间)批量选表的场景。核心是把查询结果拼成一行可复制粘贴的 shell 命令,不是自动执行——避免权限失控和误操作。
示例:生成导出当前用户下所有以 LOG_ 开头的表的命令
SELECT 'expdp ' || USER || '/password@orcl DIRECTORY=data_pump_dir DUMPFILE=log_tables_' || TO_CHAR(SYSDATE,'yyyymmdd') || '.dmp TABLES=(' ||
LISTAGG( '"' || table_name || '"', ',' ) WITHIN GROUP (ORDER BY table_name) ||
') LOGFILE=exp_log_tables.log' AS cmd
FROM user_tables
WHERE table_name LIKE 'LOG_%';
注意点:
-
LISTAGG在 Oracle 11gR2+ 才支持;11gR1 及更早版本得用WM_CONCAT(非官方函数,不推荐)或自定义聚合函数 - 拼出的命令里
PASSWORD明文暴露,生产环境应改用expdp /@orcl ...操作系统认证,或使用密码文件 - 别忘了手动检查生成的
cmd字段长度是否超 4000 字节(VARCHAR2限制),超长需分批处理
EXPDP 导出时容易忽略的三个关键参数
只写 TABLES 往往导出失败或数据不全,这几个参数决定导出内容的完整性与可用性。
-
CONTENT=DATA_ONLY:仅导出数据,跳过 DDL(建表语句)。适合已有表结构、只同步增量数据的场景 -
EXCLUDE=STATISTICS:跳过统计信息导出,加快速度,避免目标库因统计信息版本不兼容报错 -
VERSION=11.2.0.4(按目标库版本填):跨版本迁移必须显式指定,否则默认按源库版本导出,可能在低版本库无法导入
错误现象:ORA-39142: incompatible version number 就是没设 VERSION;ORA-39083 + statistics 关键字就是没加 EXCLUDE。
为什么不要在 PL/SQL 里用 UTL_FILE 手写导出逻辑
有人试图用游标 + UTL_FILE 把表数据逐行写成 CSV,这看似可控,实则埋雷:
- 字符集转换极易出错:
UTL_FILE默认按数据库字符集写文件,遇到AL32UTF8库里的中文,目标系统若用WE8MSWIN1252打开就是乱码 - 大字段(
CLOB/BLOB)无法安全拼接进字符串,DBMS_LOB.READ分块读写逻辑复杂,出错难调试 - 没有事务一致性保障:导出过程中表被 DML 修改,结果可能是“半截快照”
EXPDP 内部用闪回 SCN 保证导出时刻的一致性,这是手写脚本根本没法模拟的。真要 CSV,用 SQL*Plus 的 SET MARKUP CSV ON 更稳妥。

















