惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
V
Vulnerabilities – Threatpost
T
Tor Project blog
T
Troy Hunt's Blog
C
CERT Recently Published Vulnerability Notes
C
Cisco Blogs
W
WeLiveSecurity
Cloudbric
Cloudbric
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
爱范儿
爱范儿
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
F
Full Disclosure
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
I
Intezer
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
B
Blog RSS Feed
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
腾讯CDC
L
LangChain Blog
L
LINUX DO - 热门话题
H
Help Net Security
S
Schneier on Security
N
Netflix TechBlog - Medium
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
Spread Privacy
Spread Privacy
S
Secure Thoughts
T
The Exploit Database - CXSecurity.com
P
Privacy International News Feed
P
Privacy & Cybersecurity Law Blog
Cyberwarzone
Cyberwarzone
A
About on SuperTechFans
NISL@THU
NISL@THU
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
雷峰网
雷峰网
AWS News Blog
AWS News Blog
V2EX - 技术
V2EX - 技术

博客园 - _herbert

小程序拍证件并局部裁剪 信创-为什么ORACLE使用JDBC查询SYSDATE时,RS.getDate能获取到时间部分? linux宝塔面板使用API自动部署更新文件 JSON JAVA找出哪个类import了不存在的类 LocalDate,LocalDateTime,Date,日期串相互转换 PostMan加载三方JS PostMan内置对象 微信支付集成_JSAPI VUE中使用AXIOS包装API代理 spring中el表达式安全和扩展 Spring使用el表达式 springboot中File默认路径 Springboot启动时记录进程ID ORACLE解析游标生成JSON ORACLE游标序列化 AI教我一条SQL实现明细转树形结构 Springboot构建包使用BOOT-INF中的class覆盖依赖包中的class Maven 构建知识库 MAVEN构建分离依赖JAR JAVA实现读取最后几行日志 信创-ORACLE迁移到KingbaseV9 sql分组 group by rollup,cube,grouping sets,group_id,groupingId
信创-ORACLE迁移到DM8
_herbert · 2025-06-01 · via 博客园 - _herbert

信创-ORACLE迁移到DM8

1. DM8实列初始化

安装可以直接参考官网安装说明(安装说明)[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 }

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

/dm/dmdbms/script/root/dm_service_uninstaller.sh -n DmAPService
rm -rf /dm/data/DAMENG/*

3. 必要兼容配置

设置全局兼容参数

-- 公众号:小满小慢 小游戏: 地心侠士
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');

安装扩展包

-- 公众号:小满小慢 小游戏: 地心侠士
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权限

建立适配类型

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

建立适配视图

建立适配同义词

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";
-- 公众号:小满小慢 小游戏: 地心侠士

建立适配函数

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

关键字冲突处理

LOGIN,EXEC,XML,VIRTUAL 

重启服务

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
--- 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 模式
---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)需要做如下代码调整
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包装
---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
----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不支持默认列列类型
----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参数
---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 排序
---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 语法上不支持分组列通过子查询,转换后排序,可以嵌套一层解决
  ---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中支持中文逗号,中文括号,达梦测试也是支持,遇到了最好还是调整下代码
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. 实用查询语句

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

URL:jdbc:dm://127.0.0.1:5236?compatibleMode=oracle