通过错误的sql来测试推理sql的解析过程(二)

 之前总结过一篇  通过错误的sql来测试推理sql的解析过程 http://blog.itpub.net/23718752/viewspace-1848816/
也算是以毒攻毒,当然也分析出来一些有意思的内容来,让原本看起来枯燥的内容有了更多的实践意义。
在后来小组内部做了一个分享总结,本来以为已经总结差不多了,但是发现真是集思广益,大家临时想出不少好的点子来,这也就是brainstroming的好处吧.
比如下面的错误sql,在解析的时候,会首先报错在group by的部分。在10g和11g略微有一些差别。目前以11g的为基线。
目前存在一个表test,字段情况为(id number,name varchar2(30)),里面存在1条数据。
使用如下的语句来测试一下,会发现这样的基本规律
select id1 from test1 where id1='aaa' group by id1 having1 count(*)>0 order by5 id1
                                                   *
ERROR at line 1:
ORA-00933: SQL command not properly ended

select id1 from test1 where id1='aaa' group by id1 having count(*)>0 order by5 id1
                                                                           *
ERROR at line 1:
ORA-00924: missing BY keyword

SQL> select id1 from test1 where where1 id1='aaa' group by id1 having count(*)>0 order by5 id1;
select id1 from test1 where where1 id1='aaa' group by id1 having count(*)>0 order by5 id1
                                   *
ERROR at line 1:
ORA-00920: invalid relational operator

SQL> select id1 from test1 t where1 id1='aaa' group by id1 having count(*)>0 order by5 id1;
select id1 from test1 t where1 id1='aaa' group by id1 having count(*)>0 order by5 id1
                        *
ERROR at line 1:
ORA-00933: SQL command not properly ended
可见对于这些保留字,在解析的是按照从右向左的顺序依次来解析。
如果存在数据类型的兼容性,在隐私转换的时候如果失败,会在解析的时候一并抛出,其实这个时候已经到了执行阶段了,对于数据的细节信息无从考证,使用explain plan还是能够生成执行计划来。
SQL> select id from test t where id='aaa' group by id  order by id;
select id from test t 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> commit;
Commit complete.
这个时候再次测试,发现同样的语句在这个时候就没法直接分析出来了。这种情况看起来也是一个灰色地带。
SQL> select id from test t where id='aaa' group by id  order by id;
no rows selected
那么统计信息对于sql解析有没有影响呢?
我们收集一下统计信息,让优化器能够认为存在一条数据。
SQL> exec DBMS_STATS.SET_TABLE_STATS (ownname=>'TEST',tabname=>'TEST',numrows=>1);
PL/SQL procedure successfully completed.
再次执行同样的sql语句,发现还是没有做出更进一步的校验。
SQL> select id from test t where id='aaa' group by id  order by id;
no rows selected
如果尝试让优化器识别出数据块的情况来,是不是有改善呢?
SQL> exec DBMS_STATS.SET_TABLE_STATS (ownname=>'TEST',tabname=>'TEST',numrows=>1,numblks=>1);
PL/SQL procedure successfully completed.
情况还是类似。
SQL> select id from test t where id='aaa' group by id  order by id;
no rows selected
通过上面的结果,可以简单推论是不是和数据情况有关系呢,但是看起来关系还是不大,怎么进一步验证呢。

我们继续测试隐式转换的问题。
如果插入一条记录,但是id列为null.
SQL> insert into test values(null,'aaaaa');
1 row created.
那么同样的语句会抛出错误吗?
SQL> select id from test t where id='aaa' group by id  order by id;
no rows selected
但是继续测试,插入id为2,这个时候再次运行同样的语句就会抛错,这个也是预期这种理想的情况。
SQL> insert into test values(2,'aadbdsaf');
1 row created.

SQL> select id from test t where id='aaa' group by id  order by id;
select id from test t where id='aaa' group by id  order by id
                               *
ERROR at line 1:
ORA-01722: invalid number

继续测试索引的影响。
先清空数据。
SQL> truncate table test;   
Table truncated.
然后添加主键。
SQL> alter table test modify(id primary key);
Table altered.
这个时候再次测试就会发现同样的语句就开始抛错了,看来主键的情况还是好使,能够做一些看起来的硬验证。
SQL> select id from test t where id='aaa' group by id  order by id;
select id from test t where id='aaa' group by id  order by id
                               *
ERROR at line 1:
ORA-01722: invalid number
那么我们换个角度在索引列和非索引列上测试隐式转换的情况。
SQL> select id from test t where name=111 and id='aaa' group by id  order by id;
select id from test t where name=111 and id='aaa' group by id  order by id
                                            *
ERROR at line 1:
ORA-01722: invalid number

然后删除主键
SQL> alter table test drop primary key;
Table altered.
继续测试同样的sql语句。这个时候就校验不出来数据的细节情况了。
SQL> select id from test t where name=111 and id='aaa' group by id  order by id;
no rows selected
如果我们插入一条记录。
SQL> insert into test values(1,22222);
1 row created.
然后再次验证,会发现这条语句可以从两种可能性来理解,一种是确实没有数据,没有name列相关的数据,还没有验证到id='aaa'的情况。
SQL> select id from test t where name=111 and id='aaa' group by id  order by id;
no rows selected
那么我们使用过滤条件,指向新增加的那条记录。
SQL>  select id from test t where name=22222 and id='aaa'  group by id  order by id;
 select id from test t where name=22222 and id='aaa'  group by id  order by id
                                               *
ERROR at line 1:
ORA-01722: invalid number
就会发现有意思的问题还是发生了。
后面还有一些测试的细节,后面继续解读。

时间: 2024-09-19 23:42:23

通过错误的sql来测试推理sql的解析过程(二)的相关文章

通过错误的sql来测试推理sql的解析过程

在学习Oracle的时候,必然会接触到sql解析的过程.这个过程大体是这样的步骤. 1.对sql的文法检查,查看是否有文法错误,比如from,select拼写错误等. 2.在数据字典里校验sql涉及的对象是否存在. 3.将对象进行名称转换,比如同义词转义成对应的对象.比如select * from t t是一个同义词指向hr.test 4.检查语句的用户是否具有访问对象的权限 5.生成执行计划 6.将游标产生执行计划,sql文本装载入library cache所在的heap中. 这个过程看起来比

SQL语句的各个关键字的解析过程详细总结_MsSql

由于最近需要做一些sql query性能提升的研究,因此研究了一下sql语句的解决过程.在园子里看了下,大家写了很多相关的文章,大家的侧重点各有不同.本文是我在看了各种资料后手机总结的,会详细的,一步一步的讲述一个sql语句的各个关键字的解析过程,欢迎大家互相学习. SQL语句的解析顺序 简单的说一个sql语句是按照如下的顺序解析的: 1. FROM FROM后面的表标识了这条语句要查询的数据源.和一些子句如,(1-J1)笛卡尔积,(1-J2)ON过滤,(1-J3)添加外部列,所要应用的对象.F

SQL语句的各个关键字的解析过程详细总结

由于最近需要做一些sql query性能提升的研究,因此研究了一下sql语句的解决过程.在园子里看了下,大家写了很多相关的文章,大家的侧重点各有不同.本文是我在看了各种资料后手机总结的,会详细的,一步一步的讲述一个sql语句的各个关键字的解析过程,欢迎大家互相学习. SQL语句的解析顺序 简单的说一个sql语句是按照如下的顺序解析的: 1. FROM FROM后面的表标识了这条语句要查询的数据源.和一些子句如,(1-J1)笛卡尔积,(1-J2)ON过滤,(1-J3)添加外部列,所要应用的对象.F

关于SQL Server 2000和SQL Server 2005分布式事务能否协同工作的测试

server|分布式 关于SQL Server 2000和SQL Server 2005分布式事务能否协同工作的测试 MS DTC Report 1.      MS DTC 背景 2.      MSDTC 测试目的 3.      MSDTC 测试环境 3.1            本次验证测试环境: 3.2            环境配置 3.3            验证MSDTC 3.4            创建验证用表 4.      Linked Server测试 5.     

SQL点滴7—使用SQL Server的attach功能出现错误及解决方法

原文:SQL点滴7-使用SQL Server的attach功能出现错误及解决方法 今天用SQL Server 2008的attach功能附加一个数据库,出了点问题,提示的错误是: Unable to open physical file "D:\Documents\Dalt\XXXX.mdf" Operating system error 5: "5(error not found)" (Microsoft SQL Server: Error 5120)"

Red Gate系列之三 SQL Server 开发利器 SQL Prompt 5.3.4.1 Edition T-SQL智能感知分析器 完全破解+使用教程

原文:Red Gate系列之三 SQL Server 开发利器 SQL Prompt 5.3.4.1 Edition T-SQL智能感知分析器 完全破解+使用教程 Red Gate系列之三 SQL Server 开发利器 SQL Prompt 5.3.4.1 Edition T-SQL智能感知分析器 完全破解+使用教程 Red Gate系列文章: Red Gate系列之一 SQL Compare 10.2.0.1337 Edition 数据库比较工具 完全破解+使用教程 Red Gate系列之二

php中sql注入漏洞示例 sql注入漏洞修复_php实例

在开发网站的时候,出于安全考虑,需要过滤从页面传递过来的字符.通常,用户可以通过以下接口调用数据库的内容:URL地址栏.登陆界面.留言板.搜索框等.这往往给骇客留下了可乘之机.轻则数据遭到泄露,重则服务器被拿下.  一.SQL注入的步骤 a)  寻找注入点(如:登录界面.留言板等) b)  用户自己构造SQL语句(如:' or 1=1#,后面会讲解) c)  将sql语句发送给数据库管理系统(DBMS) d)  DBMS接收请求,并将该请求解释成机器代码指令,执行必要的存取操作 e)  DBMS

SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第3部分)(完结)

原文:SQL Server 2012:SQL Server体系结构--一个查询的生命周期(第3部分)(完结) 一个简单的更新查询 现在应该知道只读取数据的查询生命周期,下一步来认定当你需要更新数据时会发生什么.这个部分通过看一个简单的UPDATE查询,修改刚才例子里读取的数据,来回答. 庆幸的是,直到存取方法(Access Methods)前,更新操作和刚才SELECT语句流程是一模一样的. 这次存取方法(Access Methods)需要修改数据,因此在I/O请求传递前,修改的细节要存放于硬盘

分享一下SQL Server执行动态SQL的正确方式

SQL Server执行动态SQL的话,应该如何实现呢?下面就为您介绍SQL Server执行动态SQL两种正确方式,希望可以让您对SQL Server执行动态SQL有更深的了解 动态SQL:code that is executed dynamically.它一般是根据用户输入或外部条件动态组合的SQL语句块.动态SQL能灵活的发挥SQL强大的功能.方便的解决一些其它方法难以解决的问题.相信使用过动态SQL的人都能体会到它带来的便利,然而动态SQL有时候在执行性能(效率)上面不如静态SQL,而