信创-ORACLE迁移到DM8

信创-ORACLE迁移到DM8

1. DM8实列初始化

安装可以直接参考官网安装说明(安装说明)[eco.dameng.com/document/dm...]

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

/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
相关推荐
明月5667 小时前
Oracle 误删数据恢复
数据库·oracle
程序员编程指南10 小时前
Qt 数据库连接池实现与管理
c语言·数据库·c++·qt·oracle
陪我一起学编程13 小时前
MySQL创建普通用户并为其分配相关权限的操作步骤
开发语言·数据库·后端·mysql·oracle
Albert Tan13 小时前
ORACLE DATABASE 23AI+Apex+ORDS -纯享版
数据库·oracle
技术卷17 小时前
详解力扣高频SQL50题之1084. 销售分析 III【简单】
sql·leetcode·oracle
Alla T18 小时前
【通识】数据库
数据库·oracle
MickeyCV19 小时前
MySQL数据库本地迁移到云端完整教程
服务器·数据库·mysql·oracle
IT邦德19 小时前
OGG同步Oracle到Kafka不停库,全量加增量
数据库·oracle·kafka
技术卷20 小时前
详解力扣高频SQL50题之550. 游戏玩法分析 IV【中等】
sql·mysql·leetcode·oracle
技术卷1 天前
详解力扣高频 SQL 50 题之584. 寻找用户推荐人【入门】
sql·leetcode·oracle