oracle存储过程迁移达梦心得

Wesley13
• 阅读 783

这几天把项目的存储过程从oracle迁移到了达梦8,记录一下心得。国产数据库做到这样,已经算很了不起了,跟oracle兼容性确实很高。

但还是有一些细节没做好,主要是出错提示不友好,另外一个网上的资料也很少,出问题不好定位。(达梦的错误码比较简单,就是一个负数,不像oracle是ora-错误码,在百度时输入一个负数搜索信息,跟一长串错误码搜索效率差很远)

准备工作:

1 达梦的数据库管理工具默认不显示行号,也不能自动补全,需要手动设置。行号设置方法:在sql编辑页面,左侧空白竖栏(一般编辑器显示行号的地方)右击,选择”显示行号“。自动补全设置方法:在sql编辑页面空白处右击,选择“选项”,弹出的界面展开“查询分析器”,进入“编辑器”配置页面,选中“启用SQL输入助手”

2 装完达梦数据库后,需要启动oracle兼容模式sp_set_para_value(2,‘COMPATIBLE_MODE’,2);,另外,需要启动dbms_job包,SP_INIT_JOB_SYS(1)。改完设置后记得重启。

迁移碰上的问题及解决方法:

1 使用达梦的数据库迁移工具,把oracle的用户整体迁移到达梦后,是变成一个模式,而不是用户,使用起来不方便。

​ 解决方法:达梦数据库有用户和模式两个概念,库表和存储过程等是建在模式下面的,而用户则是独立的,与安全和权限功能挂钩,这跟mysql比较像。达梦的用户进行数据库操作时,默认使用同名的模式,想访问其它模式的元数据,需要显式加模式名。所以为了跟oracle保持一致,在迁移完后,需要手工给达梦添加oracle同名用户。

2 迁移后发现有一些存储过程,包等缺失。

​ 解决方法:迁移工具做得不是太好,有一些oracle数据库的元素是不会自动迁移的,需要手工处理。例如oracle的type(达梦叫“类”),一些包含达梦数据库关键字的存储过程等。(在迁移日志里面没报错的,但也是可能没迁成功,需要仔细检查)

3 oracle建SEQUENCE里面的关键字MINVALUE达梦不支持

4 达梦的关键字比oracle多很多,例如CONTEXT,bool,class,decode这些,oracle不是关键字,但达梦是。

​ 解决方法:给这些使用了关键字的字段名或者变量名加上"",并且转换成大写就可以了。例如"CLASS"

5 建了包,提示创建成功,编译有错,但没有具体说明错误地方。

​ 解决方法:可以在后面增加语句:alter package q$err_mgr compile;

6 提示“第3156 行附近出现错误[-3719]: 非法的基类名[DBMS_SQL]”

​ 解决方法:首先确认DBMS_SQL包是否启用(在左侧“工具包”菜单右键,选择启用)。如果启用了后还报这个错,则需要检查是否使用了某些DBMS_SQL的类型或者函数,在oracle有,但是在达梦没有的。

7 编译包时提示“第3494 行附近出现错误[-2193]:无效的方法名[func_name]"

​ 解决方法:这种提示原因有很多,可能是确定在包里面没有定义这个func_name,也可能是func_name不在包头里面声明,但在初始化代码里面调用。(oracle允许只在包体里面定义,达梦不允许)。也可能是调用func_name的函数跟func_name都不在包头声明,但是在包体定义时,func_name出现位置比调用处更晚,在达梦这种是不允许的。

8 regexp系统函数提示“参数不兼容”

​ 解决方法:达梦的regexp系统函数的参数名与oracle的不一样,如果原来在oracle指定了参数名,搬到达梦编译时容易出现这个错。改为非显示命名函数参数就好。

9 出现提示“第646 行附近出现错误[-3325]:包/对象[package_name]解析失败”,但646行代码是空白行

​ 解决方法:达梦的报错位置不是太准确,这种情况下一般是上下文语法解析出现问题导致的。我碰到比较多的情况是在for循环语句里面使用了case when ... end子句。达梦8对于case when支持不太好,容易把case when的end关键字与begin配对了,导致语法错乱。我的解决方法是使用decode改写case when

10 报错提示“无法解析的成员访问表达式[XXX] ”

​ 解决方法:这类错误主要是因为其它包之类的编译失效导致,需要具体分析再解决。有时会出现循环引用的情况(a包引用b包的函数,b包引用a的函数),达梦支持不太好,编译a时提示b的函数有问题,编译b时提示a的函数有问题。我的解决方法是建立一个c包,把一些代码从a和b抽出来,避免循环引用。大部分时候循环引用是可以编译过的,也可能是由于其它错误引起包编译不过,但是系统没提示好。这种情况下只要解决了另外的错误,这个循环引用编译失败的问题也就解决了。

11 提示“非法的基类名[ROWID]”

​ 解决方法:我的代码里面使用了rowid类型变量,我直接改成number了

12 达梦对于重载(覆盖)支持不太好

​ 解决方法:oracle里面两个同名函数,参数一样,只是一个是IN类型参数 ,一个是IN OUT参数,是被认为是两个不同类型的函数,可以正常重载。但达梦认为是同一个函数,编译时会出错。解决办法是把其中一个改名。另外,oracle里面varchar2(64),varchar2(1024)是两种不同的类型,可以支持重载两个函数,参数为这两种类型,但在达梦不支持。oracle里面同名的CONSTANT变量定义,后出现的会覆盖先出现的。但在达梦里面不支持。提示“错误号: -2120 无效的变量名”

迁移过程中也许还会碰上其它问题,处理原则是查官方帮助文档(在帮助菜单下面搜索,同时在安装目录下面也有很多pdf文件介绍),查百度,问官方支持。(我另了达梦的技术支持群,群里的南网工作人员还是挺热心的)

有时官方支持也搞不清楚,需要自己通过删减代码,慢慢定位问题,再自己猜测出错原因并尝试解决。

另外,之前有人写过一份教程《oracle迁移达梦常见问题汇总》 https://www.cndba.cn/foucus/article/4142 ,里面介绍了不少迁移的经验,也是值得借鉴的。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
RAC环境单实例启动数据库收到ORA
     在RAC环境中,如果你在没有启动节点的集群服务的情况下单实例启动数据库,将收到类似如下的报错:\oracle@rhel1u01\$sqlSQL\Plus:Release10.2.0.5.0ProductiononTueApr215:00:272013Copyright(
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这