专栏首页杨建荣的学习笔记通过错误的sql来测试推理sql的解析过程(二) (r8笔记第7天)

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

之前总结过一篇 通过错误的sql来测试推理sql的解析过程 也算是以毒攻毒,当然也分析出来一些有意思的内容来,让原本看起来枯燥的内容有了更多的实践意义。 在后来小组内部做了一个分享总结,本来以为已经总结差不多了,但是发现真是集思广益,大家临时想出不少好的点子来,这也就是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 就会发现有意思的问题还是发生了。 后面还有一些测试的细节,后面继续解读。

本文分享自微信公众号 - 杨建荣的学习笔记(jianrong-notes),作者:杨建荣

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-02-12

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 无意中测试了下MySQL里面的join操作,发现还是存在理解偏差

    在一个很偶然的场景下,我看到了一个关于数据库中间件的SQL测试,对比测试的内容大体是对于一条查询语句的输出。看到输出结果,虽然结果是客观的,但是我总是感觉缺少了...

    jeanron100
  • MongoDB初探第二篇 (r4笔记第82天)

    与sql语句的简单对比 在第一篇中分享了一些MongoDB的基本知识点,因为安装运行其实都还是很轻巧的,所以对于大家上手来说应该问题不大,但是安装完成,数据库也...

    jeanron100
  • 通过Maxwell解析MySQL Binlog,打好业务多活的基础

    在Binlog解析方向和数据流转方向上,经常会提到比较有名的几类工具,阿里的Canal,Zendesk的Maxwell和Yelp的mysql_streamer,...

    jeanron100
  • Bypass 360主机卫士SQL注入防御(多姿势)

    在服务器客户端领域,曾经出现过一款360主机卫士,目前已停止更新和维护,官网都打不开了,但服务器中依然经常可以看到它的身影。从半年前的测试虚拟机里面,翻出了36...

    Bypass
  • 省市县,区的查询(通过区开始)(导出的接口实现)

    wfaceboss
  • pt-osc在线重建表导致死锁的分析及对应的优化方案

    在业务低峰通过pt-osc在线做DDL期间出现死锁,导致业务的SQL被回滚了,对应用不友好。 本案例死锁发生的场景:pt-osc拷贝最后一个chunk-siz...

    老叶茶馆
  • 约束

    一 介绍 约束条件与数据类型的宽度一样,都是可选参数 作用:用于保证数据的完整性和一致性 主要分为: PRIMARY KEY (PK) 标识该字段为该表的...

    用户1214487
  • 浅谈python中的多线程和多进程(二)

    前文《浅谈python中的多线程和多进程》中我们分享过一个例子,就是分别利用python中的多线程和多进程来解决高运算量的任务,从中看出二者的一些区别。其中一点...

    一只羊
  • 面试题|无索引如何删除亿级数据?

    存在索引的情况下就比较简单,直接利用索引进行删除,写一个for 循环语句 每次删除500行,每次判断delete 影响的行数可以累加计算删除了多少行,直到删除结...

    [3306 Pai ] 社区
  • Mybatis系列第7篇:各种查询详解

    Mybatis系列目标:从入门开始开始掌握一个高级开发所需要的Mybatis技能。

    路人甲Java

扫码关注云+社区

领取腾讯云代金券