故障分析 | OceanBase 一则函数报错问题分享

作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。

本文来源:原创投稿

  • 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

    今天遇到一个 OceanBase 数据库下 Oracle 租户的 PLSQL 分隔符问题,特来分享下。

    我的初衷是对 Oracle 租户下的一张表造点随机数据,写好了 INSERT 语句,却提示没有函数 dbms_random.value 。于是查阅 OceanBase 官方文档,发现需要导入系统包 dbms_random !dbms_random 系统包存放在 OceanBase 安装目录下的 admin 子目录里,包含两个 SQL 文件,一个是包的声明 SQL:dbms_random.sql;另一个是包的定义 SQL:dbms_random_body.sql 。

    我在 obclient 下导入这两个 SQL 文件,直接报语法错误。官方给的 SQL 文件怎么可能有语法错误呢?估计是我没有完全按照文档来规范操作而导致的问题。

    最终我把报错的地方提取出来,整理成如下简单函数:

     create or replace function tt return number is<br> v1 number;<br> v2 number;<br> begin<br>   v1 := 10;<br>   v2 := sqrt(-2 * ln(v1)/v1);<br>   return v2;<br> end;<br> /<br>

    直接执行这个函数,也是报同样的错误。

    <mysql:5.6.25:SYS> create or replace function tt return number is<br>    ->  v1 number;<br>    ->  v2 number;<br>    ->  begin<br>    ->    v1 := 10;<br>    ->    v2 := sqrt(-2 * ln(v1)/v1);<br>ORA-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'sqlrt(2 * ln(v1)' at line 6<br>ORA-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'v1)' at line 1<br><mysql:5.6.25:SYS>   return v2;<br>ORA-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'return v2' at line 1<br><mysql:5.6.25:SYS> end;<br>ORA-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'end' at line 1<br><mysql:5.6.25:SYS> /<br>    -> ;<br>ORA-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near '/' at line 1<br><mysql:5.6.25:SYS><br>

    于是我把这个函数在我本地的 Oracle 环境中执行,一切正常:看来是 OceanBase 自身的环境问题。

    create or replace function tt return number is<br> v1 number;<br> v2 number;<br> begin<br>   v1 := 10;<br>   v2 := sqrt(-2 * ln(v1)/v1);<br>   return v2;<br> end;<br>  2    3    4    5    6    7    8    9   /<br><br>Function created.<br><br>Elapsed: 00:00:00.02<br>YTT@helowin> <br>

    这个函数写的非常简单,求一个给定参数的平方根。刚开始我以为函数写的有问题,于是我把函数改为这样:

    v2 := sqrt(-2 * ln(v1));

    竟然顺利执行成功了。

    <mysql:5.6.25:SYS>  create or replace function tt return number is<br>    ->  v1 number;<br>    ->  v2 number;<br>    ->  begin<br>    ->    v1 := 10;<br>    ->    v2 := sqrt(-2 * ln(v1));<br>    ->    return v2;<br>    ->  end;<br>    ->  /<br>Query OK, 0 rows affected (0.050 sec)<br>

    直到最后经过和 Oracle 环境的对比,我才发现是 PLSQL 分隔符的问题。OceanBase 的 Oracle 租户里默认 PLSQL 的分隔符是/,刚好和除法/冲突,这样遇到除法符号就以为是函数定义结束,所以报语法错误。

    那正确的写法应该是改变默认分隔符为//: 改分隔符后的函数创建成功。

    <mysql:5.6.25:SYS>delimiter //<br><mysql:5.6.25:SYS>  create or replace function tt return number is<br>    ->  v1 number;<br>    ->  v2 number;<br>    ->  begin<br>    ->    v1 := 10;<br>    ->    v2 := sqrt(-2 * ln(v1)/v1);<br>    ->    return v2;<br>    ->  end;<br>    ->  //<br>Query OK, 0 rows affected (0.114 sec)<br>

    特此分享给使用 OceanBase 的同学。

    本文关键字: #OceanBase# #Oracle租户#

          <h5 data-tool="mdnice编辑器"></h5> 
    
          <p>文章推荐:</p> 
          <p>技术分享 | OceanBase 使用全局索引的必要性</p> 
          <p>一款功能全面的 MySQL Shell 插件</p> 
          <p>使用 SQL 语句来简化 show engine innodb status 的结果解读</p> 
    
           关于SQLE 
    
          <p style='margin: 10px 0px 0px;padding: 0px;clear: both;min-height: 1em;font-style: normal;font-weight: 400;text-indent: 0px;text-transform: none;max-width: 100%;letter-spacing: 0.544px;text-align: left;font-size: 16px;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif'>爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。</p> 
    
             SQLE 获取 
    
               <table> 
    
                 <tr> 
                  <th>类型</th> 
                  <th>地址</th> 
                 </tr> 
    
                <tbody> 
                 <tr> 
                  <td>版本库</td> 
                  <td>https://github.com/actiontech/sqle</td> 
                 </tr> 
                 <tr> 
                  <td>文档</td> 
                  <td>https://actiontech.github.io/sqle-docs-cn/</td> 
                 </tr> 
                 <tr> 
                  <td>发布信息</td> 
                  <td>https://github.com/actiontech/sqle/releases</td> 
                 </tr> 
                 <tr> 
                  <td>数据审核插件开发文档</td> 
                  <td>https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html</td> 
                 </tr> 
                </tbody> 
               </table> 
    
           <p style='margin: 20px 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left'>提交有效pr,高质量issue,将获赠面值200-500元(具体面额依据质量而定)京东卡以及爱可生开源社区精美周边!</p> 
           <p style='margin: 20px 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left'>更多关于 SQLE 的信息和交流,请加入官方QQ交流群:637150065...</p> 
    
             <img src="https://img.mryunwei.com/uploads/2023/10/20231013001554579.png"> 

本文分享自微信公众号 - 爱可生开源社区(ActiontechOSS)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。