本文主要结合之前一次oracle迁移达梦的项目,将碰到的问题以及一系列踩过的坑列举出来供大家参考,数据库版本是达梦7。(本文中涉及到的部分对象名已用sch1,tab1等方式替换) 迁移过程中失败任务数低于5%,大部分对象和数据都能够保证正常迁移。其中对于出错的任务,主要有导表和导函数包两部分。其中主要棘手的在与迁移函数包等对象时的问题。 2.1、通用问题 2.1.1、关键词问题 2.1.2、中文符号的问题 2.2、表迁移问题 解决方式: 2.2.2、局部唯一索引必须包含全部分区列 解决方法: 2.2.3、记录超长 解决方法: 2.2.4、Java heap space 解决方法: 2.2.5、违反协议 解决方法: 2.2.6、ORA-08103: 对象不再存在 解决方法: 2.3、函数包等对象问题 解决方法: 2.3.2、无效的链接名 解决方法: 2.3.3、dbms_job无法使用 2.3.4、dbms_job.submit使用报错:参数不匹配 2.3.5、无法修改与非键值保存表对应的列。 解决方法: 2.3.6、无效的对象名:TAB 解决方法: 方法2: 这里建议使用方法二,直接查询sysobjects视图,DM中all_tables视图拼接的东西比较多。 2.3.7、无效的方法名: utl_encode.quoted_printable_encode 解决方法: 2.3.8、CURSOR无法作为查询项 解决方法: 2.3.9、UTL_SMTP包无法使用 2.3.10、UTL_I18N包无法使用 2.3.11、DMBS_CRYPTO包无法使用 解决方法 2.3.12、执行环境堆栈空间不足 2.3.13、DMBS_SQL包使用问题 整个迁移过程来看,大部分问题都存在于函数包等对象上,有些可以直接解决,如关键字,而有些涉及到oracle中系统包在达梦中不存在的问题就需要自己想办法去解决,例如修改代码。
0、说明
1、整体情况
2、迁移错误详解
说明:对于直接使用DTS迁移失败的包,最好从源端获取完整的定义,重新核查报错原因 —— 避免编译通过后,报错 xxx 对象未在 xxx 包中定义!(包头和包体不匹配:包头定义了三个函数,在包体中,可能只有两个函数)
a、关键词问题的处理方式
i、在包中手工改写,如,原先有变量名字为dateDiff,手动改写为“dateDiff”——用双引号屏蔽关键字。
ii、在客户端的配置文件(dm_svc.conf)中,配置对应关键字,迁移包时,不做改动,让驱动自动为我们做上述i中的事情。如下图即为配置屏蔽 TRACE和ROWS两个关键字:
达梦中的关键字可以在达梦SQL使用手册中查询,也可以使用下面SQL查询:select * from V$RESERVED_WORDS where RESERVED='Y';
a、达梦的PLSQL中,不支持中文标点、异常空白符。(即不是空格、r、n的其他的空白符、不支持全角符号 —— 当成字符串处理的除外)
b、该空白符通过客户端工具,调整编辑器为显示空白字符,可以分别异常空白符
所有正常的空格,均会显示为:虚点;如果是没有虚点的空白符,即为异常的空白符(常见于从邮件中、网页、QQ聊天框等中,直接复制出来的SQL)
2.2.1、标度大于精度
问题描述: /* 任务失败: 创建表"sch1"."tab1" */ /* 第8 行附近出现错误: 标度大于精度 */ /* 相关SQL语句: */ CREATE TABLE "sch1"."tab1" ( "REGION_NAME" VARCHAR2(20) NULL, "RATE" NUMBER(3,4) NULL, "SCORE" VARCHAR2(20) NULL, "CHECK_MONTH" VARCHAR2(20) NULL, "INSERT_TIME" TIMESTAMP(0) NULL );
达梦里面精度必须大于等于标度,精度是总长度,标度是小数位的长度,按道理小数位不可能超过总体长度的(但是oracle中并没有这个限制)。所以将NUMBER(3,4)改成NUMBER(4,4)即可。
问题描述:/* 任务失败: 创建表"sch1"."tab1" */ /* 第61 行附近出现错误: 局部唯一索引必须包含全部分区列 */ /* 相关SQL语句: */ ...
该问题是因为达梦分区表要求,如果有主键,必须包含在分区列中,所以在迁移时需要设置映射关系,将分区列映射为主键,使用复合主键的方式。
问题描述: /* 任务失败: 从"sch1"."tab1"迁移数据到"sch1"."tab1" */ /* 记录超长 */
dm7页大小设置成8k时,所有字段加起来支持的最大长度是4k。所以这种问题需要在初始化数据时将页大小设置成16k或者32k。
或者使用STORAGE(USING LONG ROW) ,达梦在建表加上这个存储选项即可突破页大小限制。
问题描述:/* 任务失败: 从"sch1"."tab1"迁移数据到"sch1"."tab1" */ /* Java heap space */
dts所在的机器内存不足导致。
问题描述:/* 任务失败: 从"sch1"."tab1"迁移数据到"sch1"."tab1" */ /* 违反协议 */
重新单独导入一遍即可。这个是oracle jdbc驱动报的错误,原因未知,可以试试在迁移工具里面指定最新的oracle jdbc驱动。
问题描述:/* 任务失败: 从"sch1"."tmp_tab1"迁移数据到"sch1"."tmp_tab1" */ /* ORA-08103: 对象不再存在 */
该问题是因为导入的表是临时表,所以导入数据时会出现这种问题,重新导入即可解决。
2.3.1、语法分析出错
问题描述:/* 任务失败: 创建自定义类型TY_SOFT_WORK_EXPERT_OBJ */ /* 第 3 行, 第 3 列[SECTION]附近出现错误: 语法分析出错 */
这类问题是因为在创建自定义类型时使用了DM7中的保留字,只需要加上双引号即可。
问题描述: /* 任务失败: 创建视图"JTITSM"."CLOUD_PERF_CURRENT" */ /* 第6 行附近出现错误: 无效的链接名[JTITSM_CLOUD] */
该问题是因为使用到了dblink,而在达梦中dblink未创建导致。
我们可以通过建立到自身的dblink,暂时绕过依赖的问题,但是自身上依然要有dblink对应的表结构,没有的话,就建一个。达梦创建dblink方法可以参考:达梦创建dblink方法。
解决方法:
达梦中支持dbms_job包,但是使用前要先启用:SQL> SP_INIT_JOB_SYS(1);
问题描述:
解决方法:
因为达梦中dbms_job.submit需要匹配5个参数,详细见达梦系统包使用手册。
问题描述:UPDATE ( SELECT A.STOP_PRODUCTION WRITE_STOP_PRODUCTION, B.STOP_PRODUCTION READ_STOP_PRODUCTION FROM E_OUTPUT_HOUR A, E_REPORT_HOUR B WHERE A.PE_ID = B.PE_ID AND A.OUTPUT_ID = B.OUTPUT_ID AND A.MEASURE_TIME = B.MEASURE_TIME ) SET WRITE_STOP_PRODUCTION = READ_STOP_PRODUCTION;
用A表去更新B表的数据,A表的关联条件必须为主键。因此修改为:UPDATE E_OUTPUT_HOUR A SET A.STOP_PRODUCTION=B.STOP_PRODUCTION from E_REPORT_HOUR B WHERE A.PE_ID = B.PE_ID AND A.OUTPUT_ID = B.OUTPUT_ID AND A.MEASURE_TIME = B.MEASURE_TIME;
问题描述: SELECT COUNT(*) INTO V_CNT FROM TAB WHERE UPPER(TNAME) = 'HIS_NE_ALARM_MSG' OR UPPER(TNAME) = 'HIS_NE_ALARM_LIST';
方法1: SELECT COUNT(*) INTO V_CNT FROM all_tables WHERE UPPER(TABLE_NAME) = 'HIS_NE_ALARM_MSG' OR UPPER(TABLE_NAME) = 'HIS_NE_ALARM_LIST';
SELECT COUNT(*) INTO V_CNT FROM sysobjects WHERE "SUBTYPE$"='UTAB' and UPPER(NAME) = 'HIS_NE_ALARM_MSG' OR UPPER(NAME) = 'HIS_NE_ALARM_LIST';
问题描述:utl_raw.cast_to_varchar2(utl_encode.quoted_printable_encode(utl_raw.cast_to_raw(substr(subject,i)))) || '?=';
达梦中utl_encode包 只有BASE64_ENCODE 和BASE64_DECODE两种方法,这里使用 BASE64_DECODE替换掉quoted_printable_encode即可。
问题描述:procedure f1(p_staff_id staff.staff_id%type, p_flow_id flow.flow_id %type, flowCursor in out refCursor) is begin open flowCursor for select b.tch_id, b.TCH_NAME, pkp_flow.getCurStaffName(b.STAFF_ID, b.person) as staff_name, CURSOR (select d.tch_id, e.staff_name, d.TCH_NAME from v_path c, v_tache d, staff e where c.tch_id = d.TCH_ID and (c.next_tch_id = b.tch_id or c.tch_id = b.TCH_ID) and c.FLOW_ID = b.FLOW_ID and d.STAFF_ID = e.staff_id) from tache_notify_staffs a, v_tache b where a.tch_id = b.tch_id and a.flow_id = b.FLOW_ID and a.staff_id = p_staff_id and b.flow_path like p_flow_id || '/%' and a.opinion is null; end f1;
达梦中无法支持此写法,需在应用程序代码中实现修改,这里先注释掉。
解决方法:
这个包在达梦新版本中已经实现,打上补丁包,然后调用系统过程创建该包。SQL> SP_CREATE_SYSTEM_PACKAGES (1,'UTL_SMTP'); DMSQL executed successfully used time: 17.984(ms). Execute id is 259.
解决方法:
达梦中没有这个包,因此无法使用,通过在达梦中自定义一个和oracle中同名的包,然后将需要用到的函数根据功能手动编写。主要用到RAWTOHEX、HEXTORAW这两个函数来实现。
问题描述:function encryptbyAes(input_string VARCHAR2,key VARCHAR2) return varchar2 IS l_type pls_integer := dbms_crypto.encrypt_aes128 + dbms_crypto.pad_pkcs5 + dbms_crypto.chain_cbc; l_encval raw(2000); begin l_encval := dbms_crypto.encrypt( src=>utl_i18n.string_to_raw(input_string,'AL32UTF8'), typ=>l_type, key=>utl_i18n.string_to_raw(key,'AL32UTF8')); dbms_output.put_line(l_encval); return l_encval; end;
因为达梦中没有该包,上面oracle中该函数主要是实现将输入的内容进行加密,然后返回加密的结果,可以改写成:function encryptbyAes(input_string VARCHAR2,key VARCHAR2) return varchar2 IS ENCRYPTED_STRING VARCHAR2(2048); l_encval VARCHAR2(2048); begin DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT( input_string, key, ENCRYPTED_STRING ); l_encval := ENCRYPTED_STRING; dbms_output.put_line(l_encval); return l_encval; end;
解决方法:
修改参数VM_STACK_SIZE = 1024后不会包该错误,但是会报嵌套层次太深的错误,当前尚未解决。
解决方法:
达梦DMBS_SQL包要使用DMBS_SQL.describe_columns获取列信息前需要先使用DBMS_SQL.execute将游标执行。3、总结
除此之外,迁移完成后可能会出现部分SQL在oracle运行速度正常,但是在达梦中运行缓慢的情况,这种情况我们还需要去调整数据库参数和优化SQL。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算