Oracle 到达梦 DTS 迁移实验记录

本次实验把 Oracle 容器作为源端,通过达梦 DTS 将 Oracle 侧对象迁移到达梦数据库。实验素材来自已解压的 metadata_only.epidm.epi.tar,其中包含两个 Oracle Data Pump 导出文件:

  • metadata_only.epidm.epi/EPI.dmp
  • metadata_only.epidm.epi/EPIDM.dmp

导出日志中可以看到参数 content=metadata_only,说明该 dump 只包含用户、表、索引、视图、过程等元数据信息,不包含表内业务数据。因此本实验更适合验证 Oracle 结构导入和 DTS 结构迁移流程;如果需要验证真实数据迁移,还需要准备包含数据的 full 或 data_only 类型 dump。

一、实验环境

项目 配置
容器平台 Docker Desktop + WSL2
Oracle 容器名 oracle23free
Oracle 镜像 gvenzl/oracle-free:23-slim
Oracle 端口 1521
Oracle 服务名 FREEPDB1
Oracle 管理用户 SYSTEM
导入文件 EPI.dmpEPIDM.dmp
源 schema EPIEPIDM
目标端 达梦数据库
迁移工具 达梦 DTS

二、实验目标

  1. EPI.dmpEPIDM.dmp 导入 Oracle 23 Free 容器。
  2. 在 Oracle 中确认 schema、表、视图、存储过程等对象是否生成。
  3. 使用达梦 DTS 连接 Oracle 源端,将对象迁移到达梦目标库。
  4. 总结迁移中需要注意的字符集、CLOB、metadata_only dump 等问题。

三、导入文件准备

在 WSL 终端中,将本地解压出来的 dump 文件复制到 Oracle 容器内:

bash 复制代码
docker exec oracle23free mkdir -p /tmp/oracle_imp

docker cp "/mnt/c/Users/Berndan Hu/Desktop/毕设/归档/打印版(1)/metadata_only.epidm.epi/EPI.dmp" \
  oracle23free:/tmp/oracle_imp/EPI.dmp

docker cp "/mnt/c/Users/Berndan Hu/Desktop/毕设/归档/打印版(1)/metadata_only.epidm.epi/EPIDM.dmp" \
  oracle23free:/tmp/oracle_imp/EPIDM.dmp

docker exec oracle23free chmod -R 777 /tmp/oracle_imp

这里使用 /tmp/oracle_imp 作为 Oracle Data Pump 的导入目录。路径中包含空格和中文时,WSL 下需要用引号包住完整路径。

四、创建 Oracle Data Pump 目录对象

进入 Oracle:

bash 复制代码
docker exec -it oracle23free sqlplus system/Oracle_123456@FREEPDB1

创建 Data Pump 目录对象:

sql 复制代码
CREATE OR REPLACE DIRECTORY IMP AS '/tmp/oracle_imp';
GRANT READ, WRITE ON DIRECTORY IMP TO SYSTEM;

SELECT directory_name, directory_path
FROM dba_directories
WHERE directory_name = 'IMP';

如果查询结果中能看到 /tmp/oracle_imp,说明目录对象已经创建成功。

五、导入 EPI 和 EPIDM

impdp 是操作系统命令,不是 SQL 命令。如果当前停在 SQL> 提示符下,需要先退出 SQL*Plus:

sql 复制代码
EXIT;

回到 WSL 终端后,再执行 Data Pump 导入。下面两条命令会把两个 dump 文件中包含的 schema 元数据全部导入到 Oracle 容器中。

1. 先创建目标 schema 用户

如果直接导入时出现下面的错误:

text 复制代码
ORA-31625: Schema EPIDM is needed to import this object, but is unaccessible
ORA-01435: user does not exist
ORA-23306: schema EPIDM does not exist

说明 dump 中的用户对象没有在当前 Oracle 23 Free 环境中成功创建。可以先手动创建 EPIEPIDM 用户,再导入 schema 下的其他对象。

进入 Oracle:

bash 复制代码
docker exec -it oracle23free sqlplus system/Oracle_123456@FREEPDB1

执行:

sql 复制代码
CREATE USER EPI IDENTIFIED BY EPI
  DEFAULT TABLESPACE USERS
  TEMPORARY TABLESPACE TEMP
  QUOTA UNLIMITED ON USERS;

CREATE USER EPIDM IDENTIFIED BY EPIDM
  DEFAULT TABLESPACE USERS
  TEMPORARY TABLESPACE TEMP
  QUOTA UNLIMITED ON USERS;

GRANT CONNECT, RESOURCE, CREATE VIEW, CREATE PROCEDURE, CREATE SEQUENCE,
      CREATE TYPE, CREATE TRIGGER, CREATE SYNONYM, CREATE DATABASE LINK
TO EPI;

GRANT CONNECT, RESOURCE, CREATE VIEW, CREATE PROCEDURE, CREATE SEQUENCE,
      CREATE TYPE, CREATE TRIGGER, CREATE SYNONYM, CREATE DATABASE LINK
TO EPIDM;

EXIT;

如果用户已经存在,CREATE USER 会提示用户已存在,这时不用重复创建,确认权限授予后继续导入即可。

2. 导入 dump 中的元数据对象

导入 EPI.dmp

bash 复制代码
docker exec -it oracle23free impdp system/Oracle_123456@FREEPDB1 \
  directory=IMP \
  dumpfile=EPI.dmp \
  logfile=impEPI.log \
  schemas=EPI \
  content=metadata_only \
  transform=segment_attributes:n \
  exclude=user,statistics

导入 EPIDM.dmp

bash 复制代码
docker exec -it oracle23free impdp system/Oracle_123456@FREEPDB1 \
  directory=IMP \
  dumpfile=EPIDM.dmp \
  logfile=impEPIDM.log \
  schemas=EPIDM \
  content=metadata_only \
  transform=segment_attributes:n \
  exclude=user,statistics

这里的"全部导入"指导入 dump 文件中包含的全部业务元数据对象,包括表、索引、视图、序列、过程、函数、触发器等。用户对象已在前一步手动创建,因此导入时使用 exclude=user 跳过 dump 中的用户创建语句。由于原始导出文件本身是 content=metadata_only,即使导入命令完整执行,也不会产生业务数据行。

content=metadata_only 与导出文件类型保持一致;transform=segment_attributes:n 用于忽略原库中的部分存储属性,减少从 Oracle 11g 导入到 Oracle 23 Free 时因为表空间、存储参数差异导致的报错;exclude=user,statistics 用于跳过用户创建和旧统计信息,后续可以在目标库中重新收集统计信息。

如果误在 SQL> 中输入了 docker execimpdp 命令,并出现 SP2-0734,说明 SQL*Plus 没有识别该命令,实际没有执行导入,也不需要回滚。直接输入 EXIT; 退出后,在 WSL 终端重新执行上述命令即可。

如果 impdp 已经执行但最后查询 dba_tablesdba_objectsEPIEPIDM 都没有对象,说明没有形成有效导入结果,也不需要回退。按上面的步骤先创建用户,再重跑导入即可。

如果导入过程中出现大量旧环境相关错误,可以使用更适合迁移实验的精简导入参数:

bash 复制代码
docker exec -it oracle23free impdp system/Oracle_123456@FREEPDB1 \
  directory=IMP \
  dumpfile=EPI.dmp \
  logfile=impEPI_clean.log \
  schemas=EPI \
  content=metadata_only \
  transform=segment_attributes:n \
  remap_tablespace=EPI_TS:USERS \
  remap_tablespace=EPI_INDEX:USERS \
  exclude=user,role_grant,default_role,tablespace_quota,object_grant,job,statistics
bash 复制代码
docker exec -it oracle23free impdp system/Oracle_123456@FREEPDB1 \
  directory=IMP \
  dumpfile=EPIDM.dmp \
  logfile=impEPIDM_clean.log \
  schemas=EPIDM \
  content=metadata_only \
  transform=segment_attributes:n \
  remap_tablespace=EPIDM_TS:USERS \
  remap_tablespace=EPIDM_INDEX:USERS \
  exclude=user,role_grant,default_role,tablespace_quota,object_grant,job,statistics

这版命令会保留表、索引、视图、序列、过程、函数、触发器等主体对象,跳过旧环境中的用户创建、角色授权、默认角色、表空间配额、对象授权、定时任务和旧统计信息。对本次 DTS 迁移实验来说,这些被跳过的对象不是核心迁移对象。

六、导入结果检查

进入 Oracle:

bash 复制代码
docker exec -it oracle23free sqlplus system/Oracle_123456@FREEPDB1

检查 schema 下表数量:

sql 复制代码
SELECT owner, COUNT(*) AS table_count
FROM dba_tables
WHERE owner IN ('EPI', 'EPIDM')
GROUP BY owner
ORDER BY owner;

检查对象类型分布:

sql 复制代码
SELECT owner, object_type, COUNT(*) AS object_count
FROM dba_objects
WHERE owner IN ('EPI', 'EPIDM')
GROUP BY owner, object_type
ORDER BY owner, object_type;

如果需要查看具体表名:

sql 复制代码
SELECT owner, table_name
FROM dba_tables
WHERE owner IN ('EPI', 'EPIDM')
ORDER BY owner, table_name;

由于 dump 是 metadata_only,表结构可以导入,但表内数据通常为空。可以选择一张表验证:

sql 复制代码
SELECT COUNT(*) FROM EPI.表名;

如果返回 0,这与 metadata_only 导出类型一致,不代表导入失败。

七、达梦 DTS 迁移配置

本节参照达梦官方 Oracle 迁移到 DM8 常见问题 进行配置,核心思路是把对象迁移拆开做:先迁移表定义,再迁移表数据,最后补约束和索引。官方文档中也提到迁移前需要确认版本、JDK、迁移顺序,并建议大表、大字段对象单独迁移;对于 Oracle 兼容性,还可将达梦静态参数 COMPATIBLE_MODE 调整为 2,重启数据库后生效。

本次实验在目标达梦库中增加了 Oracle 兼容模式参数调整:

sql 复制代码
SP_SET_PARA_VALUE(2, 'COMPATIBLE_MODE', 2);

COMPATIBLE_MODE 是静态参数,修改后需要重启数据库。该参数只能提高部分 Oracle 语法兼容性,不能保证视图、触发器、函数、包等复杂对象全部自动转换成功。

创建 DTS 迁移任务时,源端选择 Oracle,目标端选择达梦数据库。Oracle 源端使用前面 Docker 容器中导入好的 FREEPDB1 服务,迁移对象只选择业务 schema EPIEPIDM,不迁移 Oracle 系统用户。

源端和目标端连接成功后,进入对象选择页面。这里不要选择全部 schema,也不要勾选 Oracle 维护对象,只保留 EPIEPIDM。系统 schema 中存在大量 Oracle 内部对象,迁移到达梦没有意义,还会增加无关报错。

本次迁移最终按以下步骤拆分执行:

步骤 迁移内容 说明
第一步 表定义 只创建表结构,不迁移数据、约束、索引
第二步 表数据 只迁移数据,目标表沿用第一步创建的结构
第三步 约束和索引 补主键、唯一约束、外键和普通索引
第四步 序列准备尝试 该步实际还勾选了表,导致转换界面仍显示表级规则
第五步 序列 只勾选序列,作为第四步的修正执行
第六步 触发器 只迁移触发器,依赖前面已存在的表
第七步 普通视图 只迁移普通视图,不同时迁移物化视图

前三步与官方 FAQ 中"表定义、数据、约束索引分步迁移"的做法一致。后续的序列、触发器、普通视图单独迁移,是为了避免复杂对象和表对象混在一起,导致错误定位困难。

从原理上看,DTS 不是物理备份还原,也不是直接复制 Oracle 数据文件,而是通过数据库连接在源端读取元数据和数据,再在目标端生成并执行对应的 DDL、DML。一次迁移任务大致会经历以下过程:

  1. 读取源端数据字典,分析 schema、表、字段、数据类型、主键、索引、视图、触发器等对象定义。
  2. 按内置转换规则把 Oracle 对象转换成达梦对象,例如数据类型、字段长度、默认值、约束、索引和部分 SQL 语法。
  3. 在目标达梦库执行建表、建索引、加约束、创建视图等 DDL。
  4. 如果勾选数据迁移,则从 Oracle 分批查询数据,再通过批量插入写入达梦,并按设置的批量行数提交。
  5. 对视图、触发器、过程等对象,DTS 会先分析依赖和列信息。例如迁移视图前,日志中可以看到它会执行类似 SELECT * FROM "EPIDM"."DMV_LOT_CREATE_INFO" WHERE 1=2 的 SQL 来获取视图列结构。

推荐按"表定义 -> 数据 -> 约束索引 -> 序列 -> 触发器 -> 视图 -> 物化视图"的顺序迁移,本质上是按照对象依赖关系从底层到上层推进。表是最底层对象,数据依赖表,主键、外键、索引依赖表和数据,触发器依赖表和序列,视图依赖表、函数或其他视图,物化视图又依赖普通视图、基表和刷新机制。

分步迁移还有两个好处。第一,性能更稳定:先导入数据再建索引、加约束,可以减少导入过程中不断维护索引和检查约束的开销。第二,错误更容易定位:如果把表、数据、索引、触发器、视图一次性全选,日志里会混在一起,难以判断是表结构问题、数据问题,还是复杂对象兼容性问题。


第一步只迁移表定义。转换配置中保留表定义相关选项,暂不迁移数据、主键、外键、索引等对象。这样可以先保证目标端表结构落地,避免数据迁移时目标表不存在。

第二步只迁移数据。由于本次 Oracle dump 本身是 metadata_only,源端大部分业务表没有真实数据,因此数据迁移行数为空或很少是正常现象,不代表表结构迁移失败。

第三步迁移约束和索引。这里主要补充第一步没有迁移的主键、唯一约束、外键、校验约束和索引。第三步出现的两条失败 SQL 与 Oracle 内部函数索引有关:

sql 复制代码
CREATE INDEX "INDEX256247779694600"
ON "EPIDM"."DM_HGEL_REPORT"(SYS_OP_C2C("LOT"));

CREATE INDEX "INDEX256254113886900"
ON "EPIDM"."DM_XRDADDKVALUEVIEW_TEST"(SYS_OP_C2C("COMPONENTID"));

SYS_OP_C2C 是 Oracle 内部转换函数,达梦无法直接解析这类函数索引。因此这两条索引可以在本次迁移中忽略,后续如果业务查询确实需要,再在达梦侧按普通列索引重新创建。


第四步原本是准备继续迁移后续对象,但实际配置时仍勾选了表对象,所以进入"转换"后看到的仍然是表映射关系和表级迁移策略。这也是第四步报错集中在主键、唯一约束、索引重复创建上的原因。

第四步和第五步准确来说属于同一类补充对象迁移。第五步只勾选序列,不再勾选表对象,配置才是干净的序列迁移。序列不依赖表数据,但应用、触发器或过程可能会引用序列,因此放在触发器之前迁移更便于后续对象解析。


第六步迁移触发器。触发器通常依赖表、列、序列或过程,因此放在表结构、数据、约束索引和序列之后执行。本次配置只选择触发器对象,不再重复勾选表对象,避免 DTS 再次尝试创建表级约束或索引。


第七步迁移普通视图。这里仅勾选"视图",不同时勾选"物化视图"。普通视图本身不保存数据,只保存查询定义;如果源端 Oracle 视图已经无效,或者视图 SQL 中包含达梦不能直接兼容的 Oracle 写法,就会在这一阶段集中报错。


普通视图迁移完成后,再根据需要单独迁移物化视图。物化视图比普通视图依赖更重,通常依赖基表、普通视图和刷新机制,因此不建议和普通视图混在同一个任务中迁移。


Oracle 源端连接信息:

text 复制代码
数据库类型:Oracle
主机:localhost
端口:1521
服务名:FREEPDB1
用户名:SYSTEM
密码:Oracle_123456
迁移 schema:EPI、EPIDM

达梦目标端连接信息根据本机达梦实例填写,常见端口为:

text 复制代码
主机:localhost
端口:5236
用户名:SYSDBA
密码:SYSDBA 或实际密码

DTS 任务建议:

  • 如果只是验证结构迁移,也不建议一次性勾选所有对象,应按表定义、数据、约束索引、序列、触发器、视图等顺序拆分执行。
  • 如果后续拿到包含数据的 dump,先在 Oracle 中完成数据导入,再用 DTS 迁移数据。
  • 迁移前确认目标端是否已有同名对象,避免因为对象已存在导致重复创建失败。
  • 如果目标端要保留原有结构,迁移策略应选择只迁数据或跳过已存在对象。

八、常见问题记录

1. dump 导入后没有数据

本实验中的导出日志显示:

text 复制代码
content=metadata_only

这表示 dump 只包含元数据,不包含业务数据。导入后有表结构但没有表数据是正常现象。

2. impdp 提示目录或文件不存在

优先检查三点:

bash 复制代码
docker exec oracle23free ls -lh /tmp/oracle_imp
sql 复制代码
SELECT directory_name, directory_path
FROM dba_directories
WHERE directory_name = 'IMP';

还要确认 impdp 命令中的 dumpfile 名称与容器内文件名完全一致。

3. impdp 出现大量 ORA-39083

ORA-39083 表示某一类对象创建失败,需要结合后面的具体错误判断影响范围。

常见情况:

  • ORA-01919: Role ... does not exist:源库是 Oracle 11g 企业版,导入到 Oracle 23 Free 后,部分 Java、OLAP、APEX、Spatial 等旧角色不存在。对表结构迁移影响不大。
  • ORA-01917: user or role 'EPISELECT' does not exist:源库里有给 EPISELECT 账号或角色的授权,当前环境没有创建该账号。DTS 使用 SYSTEM 读取源 schema 时可以先忽略。
  • ORA-00959: tablespace ... does not exist:源库表空间如 EPI_TSEPI_INDEX 在容器库里不存在。可通过 remap_tablespace=原表空间:USERS 处理。
  • ORA-39082: created with compilation warnings:函数、视图或包已创建,但编译有警告或依赖对象缺失。迁移表结构时可以先记录,后续再单独处理。

判断是否需要回退的依据不是错误数量,而是主体对象是否已经导入。先执行第六节的对象数量检查,如果 EPIEPIDM 下已经有表、序列、过程等对象,通常可以继续做 DTS 迁移验证。

4. 同一个 schema 不要同时跑多个 impdp

如果一个 impdp 任务还在执行,又新开窗口对同一个 dump、同一个 schema 再跑一次导入,后启动的任务通常会出现:

text 复制代码
ORA-39151: Table "EPIDM"."表名" exists. All dependent metadata and data will be skipped due to table_exists_action of skip
ORA-31684: Object type ... already exists

这表示前一个任务已经创建了部分对象,后一个任务发现对象已存在,于是快速跳过。后一个任务跑得快,不代表导入更完整。

出现这种情况时,不要继续叠加第三次导入。应先让正在执行的旧任务完成,或者在旧任务的 Import> 提示符中执行:

text 复制代码
STATUS

确认进度。如果只需要表结构、不需要视图和包体,可以在 Import> 中停止旧任务:

text 复制代码
STOP_JOB=IMMEDIATE

停止后先做对象数量检查,再决定是否需要清理 schema 后重导。

本次实验中,旧的 EPIDM 导入任务最终完成,日志显示:

text 复制代码
Job "SYSTEM"."SYS_IMPORT_SCHEMA_01" completed with 141 error(s)
elapsed 0 00:33:20

剩余错误主要集中在 VIEW 创建后的编译警告,例如:

text 复制代码
ORA-39082: Object type VIEW:"EPIDM"."..." created with compilation warnings

这类信息表示视图对象已经创建,但由于依赖对象、DBLINK、函数、包或旧库环境差异,当前无法完全编译通过。对本次 Oracle 到达梦 DTS 迁移实验而言,只要表、序列、约束等主体对象已经存在,就可以继续进行 DTS 迁移验证。

5. Oracle 连接失败

先确认容器运行状态:

bash 复制代码
docker ps
docker logs -f oracle23free

如果 Oracle 尚未初始化完成,需要等待日志出现数据库 ready 相关信息后再连接。

6. 中文或 CLOB 出现问号

需要先判断源端数据是否已经损坏。Oracle 端可检查字符集:

sql 复制代码
SELECT parameter, value
FROM nls_database_parameters
WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

SELECT USERENV('LANGUAGE') FROM dual;

正常应优先使用 AL32UTF8。如果源端查询结果中已经出现 ?,说明迁移前数据已经被写坏,DTS 只能迁移当前实际内容。

九、实验结论

本次实验的关键点在于区分 Oracle Data Pump 文件的内容类型。metadata_only dump 可以用于恢复 Oracle schema 结构,再通过达梦 DTS 验证从 Oracle 到达梦的对象迁移流程,但不能用于验证真实业务数据迁移。

如果后续需要完整验证 Oracle 到达梦的数据迁移,应重新准备包含数据的 Oracle dump,导入 Oracle 容器后再执行 DTS 迁移。迁移前应先在 Oracle 源端确认字符集、表数据、CLOB 内容均显示正常,避免把源端已经损坏的数据继续迁移到达梦。

十、DTS 迁移报错分析

本次 DTS 迁移按步骤拆开后,主要报错集中在第三步、第四步和第七步。需要注意的是,第四步和第五步准确来说是同一类"补充对象迁移":第四步误勾选了表对象,因此日志中出现大量表级重复创建错误;第五步只勾选序列后,才是本次实验中真正用于迁移序列的配置。

本次用于分析的日志文件包括:

  • 所有日志.txt
  • 错误日志.txt
  • 错误sql.sql
  • 第四步错误日志.txt
  • 第四步错误sql.sql
  • 迁移普通视图错误日志.txt
  • 迁移普通视图错误sql.sql

1. 第三步:约束和索引迁移报错

第三步的目标是补充主键、唯一约束、外键、校验约束和索引。该步中需要重点关注的是 Oracle 内部函数索引无法在达梦中直接创建,例如:

sql 复制代码
CREATE INDEX "INDEX256247779694600"
ON "EPIDM"."DM_HGEL_REPORT"(SYS_OP_C2C("LOT"));

CREATE INDEX "INDEX256254113886900"
ON "EPIDM"."DM_XRDADDKVALUEVIEW_TEST"(SYS_OP_C2C("COMPONENTID"));

报错为:

text 复制代码
无法解析的成员访问表达式[SYS_OP_C2C]

SYS_OP_C2C 是 Oracle 内部转换函数,通常由 Oracle 为字符集或字符类型转换生成。达梦不能直接解析这类 Oracle 内部函数索引,因此这两条索引不影响主体表结构和数据迁移,可以在本次实验中忽略。后续如果查询确实依赖这些列,再在达梦侧补建普通索引即可:

sql 复制代码
CREATE INDEX 索引名 ON EPIDM.DM_HGEL_REPORT(LOT);
CREATE INDEX 索引名 ON EPIDM.DM_XRDADDKVALUEVIEW_TEST(COMPONENTID);

2. 第四步:误勾选表对象导致重复创建

第四步的错误日志统计如下:

失败阶段 数量 主要原因
CREATE_INDEX 878 索引已经在第三步创建,再次创建时报重复
ADD_PRIMARY_KEY 130 主键已经存在,再次添加时报重复
ADD_UNIQUE 6 唯一约束已经存在,再次添加时报重复

典型报错包括:

text 复制代码
表中已存在这样的唯一关键字或主键
此列列表已索引

这类错误不是新的迁移失败,而是第四步配置时仍勾选了表对象,DTS 再次执行表级约束和索引迁移导致的重复创建。由于第三步已经迁移过约束和索引,第四步如果只是为了迁移序列,就不应该继续勾选表映射里的主键、外键、约束和索引。

因此第五步只勾选"序列"是对第四步配置的修正。序列迁移时不需要进入表映射关系中配置主键、索引、外键等表级规则。

3. 第七步:普通视图迁移报错

第七步只迁移普通视图。日志显示:

text 复制代码
总共402个对象,实际分析402个,分析失败130个

目标端创建阶段统计如下:

失败阶段 数量 主要原因
CREATE_VIEW 200 Oracle 视图 SQL 无法直接在达梦中解析
ANALYZE_TABLE 1 DTS 分析源端视图列信息时失败

普通视图迁移失败主要有两类原因。

第一类是 Oracle 源端视图本身已经无效。日志中大量出现:

text 复制代码
ORA-04063: view "EPIDM"."..." 有错误

DTS 在迁移前会执行类似下面的 SQL 分析源端对象:

sql 复制代码
SELECT * FROM "EPIDM"."DMV_LOT_CREATE_INFO" WHERE 1=2;

如果 Oracle 源端视图已经是 invalid,DTS 读取视图结构时就会失败。这部分问题与目标达梦无关,通常和源端导入时缺少依赖对象、DBLINK、函数、包或旧环境对象有关。

第二类是视图 SQL 能从 Oracle 读出来,但不能直接在达梦中创建。迁移普通视图错误sql.sql 中失败视图大量包含中文列名和中文别名,例如:

sql 复制代码
CREATE OR REPLACE VIEW "EPIDM"."DMV_MES_EPI_WIP_LOT" ("炉次号","工单",...)
AS
SELECT LOT.LOT AS 炉次号,
       LOT.WO AS 工单,
       ...

达梦报错通常为:

text 复制代码
第 3 行, 第 19 列[?]附近出现错误:
语法分析出错

这里的 ? 多数对应中文标识符或 DTS 转换后无法识别的位置。Oracle 中能直接使用的中文别名、层次查询、部分函数写法,迁移到达梦后需要手工加双引号或改写 SQL。

例如中文别名应改为:

sql 复制代码
SELECT LOT.LOT AS "炉次号",
       LOT.WO AS "工单"

此外,普通视图 SQL 中还存在 Oracle 特有或高风险写法,例如:

  • (+ ) 旧式外连接,需要改写为 LEFT JOIN
  • CONNECT BYSTART WITH
  • SYS_CONNECT_BY_PATH
  • DECODE
  • ROWNUM
  • 部分重复列名或重复别名

因此普通视图迁移失败不代表表和数据迁移失败。视图本身只是 SQL 定义,复杂视图需要后续按业务重要性逐个改写。

4. 本次实验处理建议

本次实验可以将迁移结果分为两类看待:

对象类型 处理结论
表定义 作为主体迁移结果重点检查
表数据 由于 dump 是 metadata_only,无数据或少量数据属于正常现象
主键、唯一约束、普通索引 第三步已迁移,第四步重复报错可忽略
Oracle 内部函数索引 跳过,必要时在达梦侧重建普通索引
序列 单独迁移,不要勾选表对象
触发器 放在表、序列之后单独迁移
普通视图 失败较多,需要按业务重要性手工改写
物化视图 建议最后单独迁移,依赖普通视图和刷新机制,失败概率更高

如果要继续清理视图问题,应先在 Oracle 源端查询无效视图:

sql 复制代码
SELECT owner, object_name, status
FROM dba_objects
WHERE owner IN ('EPI', 'EPIDM')
  AND object_type = 'VIEW'
  AND status <> 'VALID'
ORDER BY owner, object_name;

SELECT owner, name, type, line, position, text
FROM dba_errors
WHERE owner IN ('EPI', 'EPIDM')
  AND type = 'VIEW'
ORDER BY owner, name, sequence;

确认源端有效后,再挑选关键视图迁移到达梦。普通视图和物化视图不建议一次性全量迁移后直接作为成功标准。

相关推荐
夜郎king1 小时前
PostgreSQL 16 搭配 PgVector:Windows 11 完整安装教程
数据库·windows·postgresql
我是一颗柠檬1 小时前
【MySQL全面教学】MySQL子查询与高级查询Day7(2026年)
数据库·后端·mysql
sN2vuQ08W1 小时前
Mysql事物的持久性及原子性
数据库·mysql
极客小云1 小时前
【从 while 循环到可视化智能体:深入拆解 Agent Loop、Codex 风格工具调用、OpenClaw 与 Hermes 背后的技术细节】
数据库·python·大模型·agent·codex·openclaw·hermes
这个DBA有点耶2 小时前
分布式数据库的“分片键”设计:选错可能让性能倒退10倍
数据库·分布式
运维行者_2 小时前
使用Applications Manager监控的关键MongoDB指标
服务器·开发语言·网络·数据库·mongodb·机器学习·云计算
一支黑色の铅笔2 小时前
MongoDB Aggregation Pipeline 常用 Stage 速查
数据库·算法·mongodb
霖霖总总2 小时前
[MongoDB小技巧02] 掌握 MongoDB 基础:容器化部署、默认配置与 mongosh 核心命令全解析
数据库·mongodb
2501_915106322 小时前
深入解析HTTPS抓包原理、中间人攻击及反抓包技术攻防
数据库·网络协议·ios·小程序·https·uni-app·iphone