Navicat不支持Oracle到PostgreSQL的备份还原,必须使用Data Transfer功能进行结构与数据的单向迁移;需手动配置传输模式、冲突处理及字段映射,并迁移后补建索引约束、统一大小写、清洗空字符串、校准字符集与时区。
不能直接“还原”,navicat 没有 oracle → postgresql 的备份文件(如 .nb3 或导出的 oracle rman 备份)兼容机制。你实际要做的,是用 data transfer 功能做一次**结构+数据的单向迁移**,不是还原。
为什么不能选“还原”或“同步”功能
Navicat 的 还原 只支持同源数据库(比如 PostgreSQL → PostgreSQL 的 .nb3 文件);数据同步 要求源和目标结构完全一致、主键/唯一约束可用,且仅限同构库(MySQL ↔ MySQL),跨 Oracle/PostgreSQL 时会报错退出或静默跳过不兼容字段。
- 常见错误现象:
Error: Unsupported data type mapping for column "CREATED_DATE" (Oracle DATE → PostgreSQL TIMESTAMP) - 同步任务启动后卡在“Comparing records”,几小时没进展——本质是类型比对失败,不是网络慢
- 即使强行勾选
Compare data,也会因 Oracle 的ROWID和 PG 的ctid不可比而漏数据
Data Transfer 设置中必须改的三项
默认配置几乎必然失败。以下三处不手动调,90% 的表会建不成功或数据错乱:
-
传输模式:必须选
Transfer structure and data(不是“仅结构”,也不是“仅数据”) -
冲突处理:勾选
Drop tables if exist—— PostgreSQL 不支持CREATE OR REPLACE TABLE,不删旧表就报relation "xxx" already exists -
高级选项 → 字段映射:点击
Edit Type Mapping,重点修正:- Oracle
NUMBER(10,0)→ 改为bigint(不是默认的integer,否则超 2147483647 就溢出变负数) - Oracle
DATE→ 改为timestamp without time zone(不是timestamp with time zone,除非你确认 Oracle 源数据带时区且已用FROM_TZ标准化) - Oracle
VARCHAR2(4000)→ 保持text(别用character varying(4000),PG 的text更稳,且避免 emoji 截断)
- Oracle
迁移后必做的三件事
Navicat 不生成索引、约束、注释,也不处理大小写和关键字冲突,这些全靠你补:
- 执行批量小写转换(Oracle 默认大写带双引号,PG 默认小写):
SELECT 'ALTER TABLE "' || tablename || '" RENAME TO ' || lower(tablename) || ';' FROM pg_tables WHERE schemaname = 'public';
再对每个表跑字段重命名语句,否则后续所有SELECT都得写"USER_NAME" - 手动重建主键和索引:Navicat 迁移只建表,不建
PRIMARY KEY或INDEX,查user_constraints和user_indexes视图导出定义,再转成 PG 语法 - 检查
NULL行为:Oracle 的空字符串''等价于NULL,但 PostgreSQL 严格区分。如果源数据混用了,迁移后需用UPDATE ... SET col = NULL WHERE col = ''清洗
最易被忽略的是字符集与时区隐式转换——Navicat 不提示,但 Oracle 客户端用 AMERICAN_AMERICA.AL32UTF8,而 PostgreSQL 默认 client_encoding = 'UTF8',若中间经过 Windows 系统或 JDBC 连接池,emoji 和中文可能变成 ??? 而不报错。务必在迁移前,在目标 PG 库执行 SHOW client_encoding; 和 SHOW timezone;,并和 Oracle 的 NLS_LANGUAGE/NLS_TERRITORY 对齐。


















