G术时刻 |GBase 8a数据库对Oracle 存储过程兼容能力-全维度适配

0 阅读4分钟

南大通用GBase 8a数据库(gbase database)的 Oracle 存储过程兼容能力,通过构建双语法解析体系,完成了从语法框架到细节规则的全量适配,实现了存量 Oracle 存储过程的无修改运行。该能力有效降低了数据库迁移的成本与风险,将原本高投入、高风险的存储过程重写工作,转化为零成本的语法适配,为企业的架构平滑升级提供了可靠的技术支撑,助力企业高效完成 Oracle 存量业务的迁移。本期内容继续拆解这套“语法翻译”黑科技,看看它是怎么做到的。

细节适配:全维度的语法差异对齐

在核心框架的基础上,针对 Oracle 与 GBase 8a 的语法细节差异,完成了全维度的适配,覆盖存储过程的全生命周期:

1.输入参数与数据类型自动映射

针对 Oracle 的参数声明顺序,调整了 yacc 语法规则,适配 Oracle 的参数定义格式;同时,实现了完整的数据类型自动映射,Oracle 的类型定义可自动转换为 GBase 8a 的等价类型,无需用户手动修改:

图片

**
**

2. 存储体结构兼容

GBase 8a 原生存储过程统一采用begin-declare-end的块结构,而 Oracle 存储过程外层采用is/as关键字完成变量声明,内层使用declare关键字,两者的块结构声明逻辑存在差异。新增 Oracle 专属的语法入口sp_tail_oracle,适配 Oracle 的块结构规则:外层通过is/as关键字识别变量声明,内层兼容declare的声明逻辑,实现了两种块结构的完整兼容。

3. 异常处理机制适配

Oracle 与 GBase 8a 的异常处理逻辑存在执行顺序的差异:

  • 用户自定义异常: 当前 GBase 8a 支持的格式是 declare condition for 加 error number,或者加 SQLSTATE 信息。Oracle 支持的格式是 declare 加异常名称,再加 exception 的结构,然后通过绑定的方式将错误码和当前的异常名称进行绑定。

    可以直接通过修改语法的方式进行兼容。

    图片

  • 异常抛出: 直接通过修改语法的方式进行兼容。

      使用 raise 语句抛出异常

          声明并抛出用户自定义异常

    图片

          重新抛出当前异常

    图片

      使用 RAISE_APPLICATION_ERROR 语句抛出异常

图片

  • 异常处理机制:GBase 8a 原生的异常处理逻辑,要求先声明异常处理规则,再执行业务代码,这样执行过程中出现异常时,系统可以直接找到对应的处理方式;但 Oracle 的语法规则是,先写业务执行代码,再写异常处理的规则,两者的执行顺序刚好相反。

    为了适配这个差异,增加了跳转指令的处理逻辑:当解析 Oracle 格式的代码时,读到业务块的开头后,会先跳转到后面的异常处理部分,提前把异常处理规则注册好,再回到开头执行业务代码,以此对齐两边的执行逻辑。哪怕是嵌套的异常处理场景,内层抛出的异常、外层的捕获逻辑,也都能正常生效。同时我们增加了前置检查:如果当前的业务块里没有定义异常处理规则,就会自动跳过这个跳转操作,并且在后续的指令优化阶段,把这个无效的跳转指令清理掉,不会对代码的执行效率造成影响。

4.结束符规则适配

**
**

针对 Oracle 以单独行/作为存储过程结束符的习惯,制定了明确的识别规则,区分结束符与除法运算符:

  1. 结束符严格遵循’/’结束,且当前行有且仅有一个有效字符’/’ (空格除外)

  2. 如果某一行包含’/’,且有其他字符(空格除外)时,则认为当前存储过程没有输入完全,如用例 2 和 3

  3. 一行中其他字符不认为是结束符,包括原始 GBase 8a 默认结束符,均视为普通字符

  4. 遇到结束符后,将其前面所有字符作为完整语句发送给客户端

5. 绑定变量语法适配

针对 Oracle 的:变量绑定变量语法,实现了自动转换为 GBase 8a 的@变量语法,同时对齐了变量的作用域、赋值逻辑,保证执行结果的一致性:

图片

效果:用户无感,迁移平滑

所有这些语法兼容工作,对最终用户是透明的。原来在Oracle上写的存储过程,只要语法符合兼容范围,拿到GBase 8a上就能跑,不需要重写业务逻辑。