信创-ORACLE迁移到DM8

信创-ORACLE迁移到DM8

1. DM8实列初始化

安装可以直接参考官网安装说明(安装说明)[eco.dameng.com/document/dm...](https://link.juejin.cn?target=https%3A%2F%2Feco.dameng.com%2Fdocument%2Fdm%2Fzh-cn%2Fpm%2Finstall-uninstall.html "https://eco.dameng.com/document/dm/zh-cn/pm/install-uninstall.html")

安装完成后使用如下命令初始数据库

/dm/dmdbms/bin/dminit path=/dm/data PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=0 CASE_SENSITIVE=1 PORT_NUM=5236 BLANK_PAD_MODE=1 SYSDBA_PWD=123456 SYSAUDITOR_PWD=123456

其中参数 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=0 CASE_SENSITIVE=1 BLANK_PAD_MODE=1 迁移工具SQLark有校验这些参数,配置必须包含这些参数

2. DM8服务注册

切换到root用户 su root

dm/dmdbms/script/root/root_installer.sh

安装完成后服务名为 DmAPService

  • 可以使用 systemctl start DmAPService 启停服务
  • 也可使用 dm/dmdbms/bin/DmAPService 启停服务

Usage: ./DmAPService { start | stop | status | condrestart | restart }

如果初始配置错误可以使用以下命令删除实列,重新初始化

shell 复制代码
/dm/dmdbms/script/root/dm_service_uninstaller.sh -n DmAPService
rm -rf /dm/data/DAMENG/*

3. 必要兼容配置

设置全局兼容参数

sql 复制代码
-- 公众号:小满小慢 小游戏: 地心侠士
SP_SET_PARA_VALUE(2,'COMPATIBLE_MODE',2);
SP_SET_PARA_VALUE(2,'CALC_AS_DECIMAL',1);
SP_SET_PARA_VALUE(2,'ORDER_BY_NULLS_FLAG',1);
SP_SET_PARA_VALUE(2,'PK_WITH_CLUSTER',0); 
SP_SET_PARA_VALUE(2,'ENABLE_CS_CVT',1);--启用编码转换,类型转换用cast
SP_SET_PARA_VALUE(2,'ENABLE_TABLE_EXP_REF_FLAG',1);
--查询单个配置参数使用 SF_GET_PARA_VALUE 函数
select SF_GET_PARA_VALUE(2,'COMPATIBLE_MODE');

安装扩展包

sql 复制代码
-- 公众号:小满小慢 小游戏: 地心侠士
SP_CREATE_SYSTEM_PACKAGES(1,'DBMS_XMLDOM');
SP_CREATE_SYSTEM_PACKAGES(1,'DBMS_XMLPARSER');
SP_CREATE_SYSTEM_PACKAGES(1,'DBMS_XMLPARSER');
SP_CREATE_SYSTEM_PACKAGES(1,'DBMS_JOB');
DMBS_JOB GRANT DBA TO 用户名; -- JOB必须要添加DBA权限

建立适配类型

sql 复制代码
CREATE OR REPLACE TYPE ODCIVARCHAR2LIST AS VARRAY(32767) OF VARCHAR2(4000);
--公众号:小满小慢 小游戏: 地心侠士

建立适配视图

建立适配同义词

sql 复制代码
CREATE OR REPLACE SYNONYM COLS FOR USER_TAB_COLS; 
CREATE OR REPLACE SYNONYM "XMLDOM" FOR "SYS"."DBMS_XMLDOM";
CREATE OR REPLACE SYNONYM "XMLPARSER" FOR "SYS"."DBMS_XMLPARSER";
-- 公众号:小满小慢 小游戏: 地心侠士

建立适配函数

sql 复制代码
-- 解决达梦没有nls_charset_id而Oralce有,达梦默认不使用这个参数,返回null即可
CREATE OR REPLACE OR REPLACE FUNCTION NLS_CHARSET_ID(NAME IN VARCHAR2) RETURN INTEGER AS
BEGIN
 -- 公众号:小满小慢 小游戏: 地心侠士
 RETURN NULL;
END;

关键字冲突处理

sql 复制代码
LOGIN,EXEC,XML,VIRTUAL 

重启服务

shell 复制代码
dm/dmdbms/bin/DmAPService restart

4. 迁移必须步骤

为了保障数据库迁移的准确度,总结为以下4步骤

  1. 迁移表结构
  2. 迁移表数据
  3. 迁移触发器外的所有脚本
  4. 迁移触发器
  5. 迁移完成后,确保启用所有触发器

5.特殊语法处理

  • 迁移过程中SYS_CURSOR有几率被转换成SYS CURSOR,需要修改为SYS_CURSOR 重新执行.
  • 不支持数据隐式转换,需要调用CAST(value AS 类型说明)转换类型(后测试支持)
  • 参数默认值不支持V_PARAM in Integer :=2 的写法,需要调整成 V_PARAM in intger default 2
sql 复制代码
--- ORACLE----
CREATE Function format(v_Dec Integer := 2) Return Varchar2;
--- DM8----公众号:小满小慢 小游戏: 地心侠士
CREATE Function format(v_Dec intger default 2) Return Varchar2;
  • 不支持在SYS模式下建立类型,SYS.ODCIVARCHAR2LIST 需要去掉 SYS 模式
sql 复制代码
---ORACLE--
SELECT * FROM TABLE(SYS.ODCIVARCHAR2LIST(1,2,3,4,5))
---DM8--公众号:小满小慢 小游戏: 地心侠士
SELECT * FROM TABLE(ODCIVARCHAR2LIST(1,2,3,4,5))
  • 不支持实用xmltype直接序列化游标 xmltype(sys_refcursor)需要做如下代码调整
sql 复制代码
declare
   CTX DBMS_XMLGEN.CTXHANDLE;
   x           xmltype;
   str varchar2(2000);
   sysCursor sys_refcursor;
begin
   open sysCursor for select 1 F_A from dual;
   -----Oracl语句------
   x   := xmltype(sysCursor);
   str := x.extract('/*/ROW').getClobVal(0, 0);
   -- 公众号:小满小慢 小游戏: 地心侠士
   -----DM8语句-----
   CTX := DBMS_XMLGEN.NEWCONTEXT(sysCursor); -- 转换游标
   str := EXTRACT(DBMS_XMLGEN.GETXML(CTX), '/*/ROW'); -- 查询xml
   DBMS_XMLGEN.CLOSECONTEXT(CTX); -- 关闭hander
end;
  • XMLForest生成xml时,如果嵌套XMLELEMENT使用内容做了xml转义,需要使用xmltype包装
sql 复制代码
---ORACLE---
WITH T AS (SELECT 1 F_A, 2 F_B FROM DUAL)
SELECT XMLELEMENT("ROW_DATA", XMLFOREST(F_A, F_B)).GETCLOBVAL() AS ABC
FROM T;
---DM8--- 公众号:小满小慢 小游戏: 地心侠士
WITH T AS
(SELECT 1 F_A, 2 F_B FROM DUAL)
SELECT XMLELEMENT("ROW_DATA", XMLTYPE(XMLFOREST(F_A, F_B))).GETCLOBVAL() AS ABC
FROM T;
  • 不支持XMLTYPE.gettCLOBVAL的静态方法,必须先有xmltype
sql 复制代码
----Oracle---
with t as (select 1 F_A, 2 F_B from dual)
SELECT Xmltype.getClobVal(xmlelement("A", F_A)) AS ABC FROM t;
----DM8--- 公众号:小满小慢 小游戏: 地心侠士
with t as (select 1 F_A, 2 F_B from dual)
SELECT xmlelement("a",F_A).getClobVal() AS ABC FROM t;
  • XMLTALBE 解析XML不支持默认列列类型
sql 复制代码
----Oracle---
select x.*
from xmltable('/rows/row' passing
               xmltype('<rows><row><name>test</name></row></rows>')
               columns xml_NAME path 'name') x
--DM8---
select x.*
from xmltable('/rows/row' passing
               xmltype('<rows><row><name>test</name></row></rows>')
               columns xml_NAME varchar2(100) path 'name') x
  • UTL_HTTP.WRITE_RAW 不支持Blob参数
sql 复制代码
---Oracle---
PROCEDURE write_raw(r IN OUT NOCOPY req,data IN RAW);
---DM8--- 公众号:小满小慢 小游戏: 地心侠士
PROCEDURE WRITE_RAW(r IN OUT NOCOPY REQ,data IN VARBINARY);
--达梦实现Blob转varbinary(不能直接使用cast转换)
DECLARE
  l_blob_data BLOB;
  bin varbinary ;
BEGIN
  l_blob_data := HEXTORAW('0123456789ABCDEF');
  Dbms_lob.READ(l_blob_data,cast(dbms_lob.GETLENGTH(l_blob_data) as INTEGER),1,bin);
  dbms_output.put_line(bin);
END;
  • Group by rollup 数据没有按照明细小计汇总的方式排序,需要显示指定排序,可以直接使用 rollup(a,b) order by grouping(a),a,b 排序
sql 复制代码
---oracle--- 默认按照明细 小计 合计顺序排序
with t as
 (select 1 as F_A, 'a' as F_C, 'L1' F_D
    from dual
  union all
  select 1 as F_A, 'a' as F_C, 'L2' F_D
    from dual
  union all
  select 1 as F_A, 'b' as F_C, 'L1' F_D
    from dual
  union all
  select 1 as F_A, 'b' as F_C, 'L2' F_D
    from dual)
select decode(grouping(F_C), 1, '合计', F_C),
       decode(grouping(F_D) + grouping(F_C), 1, '小计', F_D), sum(F_A),
       grouping(F_C), grouping(F_D), GROUP_ID()
  from t
 group by rollup(F_C, F_D);
 ---dm--- 默认按照 明细,小计,合计 顺序排序
  with t as
 (select 1 as F_A, 'a' as F_C, 'L1' F_D
    from dual
  union all
  select 1 as F_A, 'a' as F_C, 'L2' F_D
    from dual
  union all
  select 1 as F_A, 'b' as F_C, 'L1' F_D
    from dual
  union all
  select 1 as F_A, 'b' as F_C, 'L2' F_D
    from dual)
select decode(grouping(F_C), 1, '合计', F_C),
       decode(grouping(F_D) + grouping(F_C), 1, '小计', F_D), sum(F_A),
       grouping(F_C), grouping(F_D)
  from t
 group by rollup(F_C, F_D) order by grouping(F_C),F_C, F_D; --需要指定排序
  • group by groupset 语法上不支持分组列通过子查询,转换后排序,可以嵌套一层解决
sql 复制代码
  ---ORACLE---
  with t as
  (select 1 F_SHENID, '广东' F_SHENMC from dual),
  d as
  (select 1 F_SHENID, '深圳' F_CS, '宝安' F_JC, 100 F_RS
      from dual
    union all
    select 1 F_SHENID, '广州' F_CS, '白云' F_JC, 150 F_RS
      from dual)
  select (select F_SHENMC from t where t.F_SHENID = d.F_SHENID) as F_SHENMC,
        F_SHENID, F_CS, F_JC, sum(F_RS) F_RS
    from d
  group by GROUPING SETS((F_CS, F_JC),(F_SHENID, F_CS, F_JC))
  order by F_SHENMC;  --DM这里报错 [-4080]:第14行附近出现错误:不是 GROUP BY 表达式
---DM8--- 公众号:小满小慢 小游戏: 地心侠士
-- 要么不使用F_SHENMC排序,要么使用嵌套查询解决排序问题
select * from (
with t as
 (select 1 F_SHENID, '广东' F_SHENMC from dual),
d as
 (select 1 F_SHENID, '深圳' F_CS, '宝安' F_JC, 100 F_RS
    from dual
  union all
  select 1 F_SHENID, '广州' F_CS, '白云' F_JC, 150 F_RS
    from dual)
select (select F_SHENMC from t where t.F_SHENID = d.F_SHENID) as F_SHENMC,
       F_SHENID, F_CS, F_JC, sum(F_RS) F_RS
  from d
 group by GROUPING SETS((F_CS, F_JC),(F_SHENID, F_CS, F_JC)))
 order by F_SHENMC;
  • ORACLE在PL/SQL中支持中文逗号,中文括号,达梦测试也是支持,遇到了最好还是调整下代码
sql 复制代码
with t as (select 1 F_A,'a' F_B from dual)
select * from t where t.F_B in ('a')
---动态sql-- 公众号:小满小慢 小游戏: 地心侠士
DECLARE
sqltxt VARCHAR2(200);
cur    SYS_REFCURSOR;
a      number;
b      VARCHAR2(100);
BEGIN
  sqltxt := 'with t as (select 1 F_A,''a'' F_B from dual)
select * from t where t.F_B in (''a'')';
  OPEN cur FOR sqltxt;
  LOOP
    FETCH cur
      INTO a, b;
    EXIT WHEN cur%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE('F_A: ' || a || ', F_B: ' || b);
  END LOOP;
  CLOSE cur;
END;

6. 实用查询语句

sql 复制代码
SELECT * FROM V$DM_INI; -- 查询配置信息
SELECT * FROM V$VERSION; --查询数据库版本信息
SELECT * FROM V$INSTANCE; --查询实列信息,数据库版本信息
SELECT * FROM V$LICENSE; --查询LINCE,数据库到期日期
SELECT * FROM V$SESSIONS; --查询会话信息
select SF_GET_PARA_VALUE(2,'ENABLE_CS_CVT');--查询配置参数
select * from V$RESERVED_WORDS t; --查询关键字
--公众号:小满小慢 小游戏: 地心侠士
--安装,卸载,检查,扩展包
SP_CREATE_SYSTEM_PACKAGES (1,'DBMS_XMLDOM');
SP_CREATE_SYSTEM_PACKAGES (0,'DBMS_XMLDOM');
SELECT SF_CHECK_SYSTEM_PACKAGE('DBMS_XMLDOM');

--查询所有表信息
select * from user_tables;
select OWNER,TABLE_NAME,TABLESPACE_NAME,TEMPORARY,STATUS,PARTITIONED,DROPPED from all_tables;

--查询所有列信息
SELECT OWNER,TABLE_NAME,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,NULLABLE FROM ALL_TAB_COLUMNS

--查询所有函数,存储过程,程序包
SELECT OWNER,OBJECT_NAME,PROCEDURE_NAME,OBJECT_TYPE,AGGREGATE,PIPELINED,PARALLEL FROM ALL_PROCEDURES

--查询所有参数信息
select OWNER,OBJECT_NAME,PACKAGE_NAME,ARGUMENT_NAME,POSITION,DATA_TYPE,DEFAULTED,DEFAULT_VALUE,IN_OUT,DATA_LENGTH from ALL_ARGUMENTS

--查询所有对象(SCHOBJ,TABOBJ,UR,SCH,DSYNOM,PROFILE)
select OWNER,OBJECT_NAME,OBJECT_TYPE,STATUS from ALL_OBJECTS

--查询函数,存储过程,类型,触发器代码
select * from ALL_SOURCE

--查询所有视图代码
select OWNER,VIEW_NAME,TEXT from ALL_VIEWS

7. JDBC数据连接配置

JDBC连接需要指定兼容模式为ORACLE

properties 复制代码
URL:jdbc:dm://127.0.0.1:5236?compatibleMode=oracle
相关推荐
ClouGence7 天前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
ClouGence14 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
曹牧14 天前
Oracle EXPLAIN PLAN
数据库·oracle
贤时间14 天前
codex 助力oracle ebs 开发
数据库·oracle
秉承初心14 天前
PostgreSQL 数据性能瓶颈突破实战
数据库·postgresql·oracle
Curvatureflight15 天前
MySQL 深分页越来越慢?从 LIMIT OFFSET 改成游标分页
数据库·oracle
XZ-07000115 天前
MySQL事务
数据库·mysql·oracle
tiancaijiben15 天前
阿里云函数计算FC如何实现网站的定时任务与自动化
数据库·oracle·dba
xfhuangfu15 天前
Oracle 19c 多租户体系架构介绍
数据库·oracle·架构
杨云龙UP15 天前
Spotlight 接入 Oracle 数据库监控操作指南 2026-06-16
数据库·oracle·性能监控·预警·阈值·spotlight·瓶颈分析