设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 手机 数据 公司
当前位置: 首页 > 服务器 > 安全 > 正文

一个SQL语句引发的ORA-00600错误排查(2)

发布时间:2021-01-08 01:06 所属栏目:53 来源:网络整理
导读:所以经过上面的排除之后,我们需要重新审视这个语句,看看是否存在一些隐患. 4 模拟复现问题 经过反复测试之后,我发现这个问题可以很容易复现. 当然我换一个方式来说明,我可以创建一个表,然后模拟这个ORA-00600的错误

所以经过上面的排除之后,我们需要重新审视这个语句,看看是否存在一些隐患.

4模拟复现问题

经过反复测试之后,我发现这个问题可以很容易复现.

当然我换一个方式来说明,我可以创建一个表,然后模拟这个ORA-00600的错误.

创建测试表test_bug

然后使用如下的语句尝试生成执行计划.

可能眼尖的朋友发现这个里面有些语法问题,这也是我无意中埋下了几个探针,如果你看到语句哪里有问题,后续分析就会明白了.

这个语句里的问题我是可以保持了(select * from test_bug where object_type=’TABLE’) t 这个子查询,抛出了ORA-00600的错误,我简化一番如何,简化为(select*from test_bug)t这个子查询,同样还是会抛出一样的错误.

我们来回过头来翻翻旧账,刚刚的语句的问题在如下红框的几个地方,在解析的时候都没有抛出错误,可见问题是出在这些之前,那么推理只有test_bug相关的子查询了.

修复这几个语法问题之后,使用下面的方式就没有问题了,最后调用成功的语句如下,我们把子查询替换为表test_bug

我们来反思一下,其实我们所写的merge语句都是merge into table_xx using(xxxx) on (xxx)的形式.

在table_xx的地方加入子查询,可能会让我们在联想到一些语句中使用子查询的DML方式,但是在merge语句中,这个地方会有问题,所幸的是这个问题目前的测试没有发现对线上环境产生严重的影响,需要引以为戒,不过问题还不能这么轻易下结论,我们继续往下看.

5认知的反转

如果只是像上面那么想,充其量只是一个攻略,而且你对Merge印象会更加糟糕.

难道是Merge有什么特别之处吗,我们来看看Oracle的官方对于Merge语句的解释.可以看到merge into后面可以是table或者是view.

我在上面的测试使用的是子查询,那么试试view可不可行呢.

我们创建一个view.

create view test_view as select * from test_bug where object_type=’TABLE’;

我滴个神,这个问题确实就是这么任性,那么我们是不是可以得出一个结论,在merge into的后面只能使用table或者view,不能使用子查询呢,还是不要过早下结论.

6持续反转(二)

对于这个问题,我们也进行了小范围的讨论,兔子大师在看到我的这个问题之后,在11.2.0.4的版本中进行了测试,之前我碰到的那个问题在这个版本中就不复存在了,兔子威武.

测试复现的过程很简单:

create table test_bug as select * from dba_objects where rownum<1;

解析生成执行计划,可以看到这个时候就没有问题了.

可见这个问题在11.2.0.4之前的版本会抛出ORA-00600,算是一个bug中的bug吧.

7简单总结

通过上面波澜起伏的测试和复现、验证,我们可以得出这样的一个结论:这个问题和表中的数据量无关,和是否使用子查询也没有关系,是在特定版本中出现的一个特定的问题,当然明白了原委,我们完全可以规避这个问题.

而且这个场景中Merge的使用有些不太到位,其实也可以考虑使用INSERT语句来实现.

8反思

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读