通过错误的sql来测试推理sql的解析过程(r7笔记第31天)

在学习Oracle的时候,必然会接触到sql解析的过程。这个过程大体是这样的步骤。

1.对sql的文法检查,查看是否有文法错误,比如from,select拼写错误等。

2.在数据字典里校验sql涉及的对象是否存在。

3.将对象进行名称转换,比如同义词转义成对应的对象。比如select * from t t是一个同义词指向hr.test

4.检查语句的用户是否具有访问对象的权限

5.生成执行计划

6.将游标产生执行计划,sql文本装载入library cache所在的heap中。

这个过程看起来比较容易理解,但是实际中我们也不能死记硬背,如果想推理一下其中的有些步骤,其实不用很精细的trace也可以办到。我们就用最简单的sql语句来测试。

当然思路需要转换,要测试的是存在问题的sql语句,看oracle的编译器会给我们什么样的解释。

首先准备一个测试表

create table test (id number,name varchar2(30));

准备好之后,就开始测试一下。不过思路是用有问题的语句来测试,来推理。

下面的语句存在很多的问题,来看看oracle的反应。

select1 id1 from2 test1 where3 id1='aaa' group by4 id1 order by5 id1

*

ERROR at line 1:

ORA-24333: zero iteration count

首先解析发现select的语句错误其实后面from,where,group by,order by都有错误。但是首先发现是select的部分。可见解析还是从左至右的方向来做文法解析。

接着修复select的文法错误,来继续看看。

select id1 from test1 where3 id1='aaa' group by4 id1 order by5 id1

*

ERROR at line 1:

ORA-00933: SQL command not properly ended

这个时候错误指向了id1而没有指向where3,可见编译器在处理的时候可能不知道该怎么处理了。这一点上出乎我的意料。修复where的文法错误继续测试。

select id1 from test1 where id1='aaa' group by4 id1 order by5 id1

*

ERROR at line 1:

ORA-00924: missing BY keyword

这个时候直接指向了group by的部分。通过这三个例子可以基本推理出文法解析是从左至右。对于是否存在表,是否字段存在问题都先不会解析。

然后我们修复了group by,order by的文法错误,继续测试。

select id1 from test1 where id1='aaa' group by id1 order by id1

*

ERROR at line 1:

ORA-00942: table or view does not exist

发现错误指向了test1,发现没有这个表。可见在文法解析之后开始校验是否存在这个表。这个时候还没有开始校验字段的情况。

修复了表名的错误,继续测试。

select id1 from test where id1='aaa' group by id1 order by id1

*

ERROR at line 1:

ORA-00904: "ID1": invalid identifier

发现这个时候是在解析group by 的字段名,对于select,where,order by中的先不解析。

然后修复group by中的错误,继续测试。

select id1 from test where id1='aaa' group by id order by id1

*

ERROR at line 1:

ORA-00904: "ID1": invalid identifier

发现解析到了where 子句中的字段值。这个时候select,order by中还没有开始解析。

修复where子句中的问题,继续测试。

select id1 from test where id1='aaa' group by id order by id1

*

ERROR at line 1:

ORA-00904: "ID1": invalid identifier

这个时候错误就指向了select子句,这个时候就剩下了order by的部分。

修复select的部分。继续测试。

SQL> select id from test where id='aaa' group by id order by id1;

select id from test where id='aaa' group by id order by id1

*

ERROR at line 1:

ORA-00904: "ID1": invalid identifier

终于指向了order by,可见order by的部分是语句执行的最后的部分。

通过上面的错误测试,可以发现能够基本得到语句解析中的处理顺序。

我们更深一步。看看如果字段id为number,赋予varchar2的数据,是否会在解析的时候校验出来。

SQL> select id from test where id='aaa' group by id order by id;

select id from test where id='aaa' group by id order by id

*

ERROR at line 1:

ORA-01722: invalid number

这个时候发现错误已经在校验数据的类型了。

怎么看出在解析的时候是否校验了数据类型呢,别急,来做一个操作即可。

SQL> delete from test ;

1 row deleted.

然后再次执行上面的语句。

SQL> select id from test where id='aaa' group by id order by id;

no rows selected

就会发现这个时候oracle好像处理不了这种场景了。

好了,oracle编译器已经很强大了。我们就最后以一个基本正常的语句结束。

SQL> select id from test where id='100' group by id order by id;

no rows selected

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2015-11-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

第三十天-加强2-多表查询&JDBC&连接池&DBUtils&综合案例【悟空教程】

第三十天-加强2-多表查询&JDBC&连接池&DBUtils&综合案例【悟空教程】

1614
来自专栏乐沙弥的世界

Oracle 硬解析与软解析

Oracle 硬解析与软解析是我们经常遇到的问题,什么情况会产生硬解析,什么情况产生软解析,又当如何避免硬解析?下面的描述将给出

1083
来自专栏数据和云

Oracle 数据库之最:你见过最高的 SQL Version 是多少?

Oracle数据库中执行的SQL,很多时候会因为种种原因产生多个不同的执行版本,一个游标的版本过多很容易引起数据库的性能问题,甚至故障。 有时候一个SQL的版本...

3025
来自专栏后台架构

Sphinx源码学习笔记(一):索引创建

  因为项目开发需要在游戏内部实现玩家名称的模糊查找功能,本身直接使用Sphinx配置mysql可以直接搭建一套模糊匹配的即可支持功能的实现。

4437
来自专栏IT杂记

关于MySQL DNS解析探究之二:unauthenticated user

把这篇没写完的文章写完,2015年的事就不留到2016了 开启DNS解析 mysql> show variables like 'skip_name_resol...

2638
来自专栏听Allen瞎扯淡

Fetch Size 与 JDBC 内存管理

接触到 JDBC 的 Fetch Size 这个属性缘起一个性能问题,项目中需要将一个有千万级数据量的表中的记录导出到文件中去。按照正常的路数,先初始化连接;接...

1572
来自专栏Flutter&Dart

DartVM服务器开发(第十五天)--Jaguar_ORM一对一

HasBean绑定一个bean 下面我们来新建Avatar这个类,从意思上,该实体类为用户的头像

1603
来自专栏Snova云数仓

Greenplum资源队列初识

在Greenplum的4.x版本之后,加入了资源队列的概念,其主要作用就是限制用户或者单个SQL对资源的消耗。避免出现消耗过多资源,影响其他用户或者SQL计算。...

65914
来自专栏Java帮帮-微信公众号-技术文章全总结

day26.MySQL【Python教程】

1326
来自专栏有趣的Python

(旧) 1- 大家一起学:Flask构建弹幕微电影网站-(一)-(三)合集:数据模型设计映射成表Flask 构建微电影视频网站

Flask 构建微电影视频网站 已上线演示地址: http://movie.mtianyan.cn 项目源码地址:https://github.com/mti...

4925

扫码关注云+社区

领取腾讯云代金券