同样的sql执行结果不同的原因分析 (r4笔记第27天)

今天开发的同事问我一个问题,说有一个sql语句,在weblogic的日志中执行没有结果,但是手动拷贝数据到客户端执行,却能够查到。这种奇怪的问题一下子就能引起我的好奇心,从我知道的原因来看啊,可能是存在不可见字符造成的。 对于不可见字符的问题,有必要先说明一下,可以简单举个例子。 我们创建一个表,然后插入的数据含有不可见字符,比如回车,换行符。 SQL> create table test as select object_id,object_name||chr(10) objname from all_objects where rownum<3; Table created

插入数据之后,我们查看一下数据。 SQL> select *from test; OBJECT_ID OBJNAME ---------- ------------------------------- 20 ICOL$ 46 I_USER1 简单的验证一下,可以看到object_id=46对应的是objname为I_USER1的数据行。

SQL> select *from test where objname='I_USER1'; no rows selected --但是查询的时候却没有任何结果 如果我们在查询中明确的加入那个不可见字符,就可以很容易就插叙出来。

SQL> select *from test where objname='I_USER1'||chr(10); OBJECT_ID OBJNAME ---------- ------------------------------- 46 I_USER1 这个时候可以使用dump函数来分析。 如果可以对比一下数据的dump细节,可以发现唯一的差比是最后有一个chr(10)的字符

SQL> select object_id,dump('I_USER1') DUMP1,dump(objname) DUMP2 from test where objname like 'I_USER%';

OBJECT_ID DUMP1 DUMP2 ---------- ---------------------------------- -------------------------------------------------- 46 Typ=96 Len=7: 73,95,85,83,69,82,49 Typ=1 Len=8: 73,95,85,83,69,82,49,10 但是当我自信满满的查看了开发提供的日志之后,然后在客户端中又执行了一遍,发现问题似乎比预想的更有些奇怪。 语句是一个简单的select语句,类似select xxxx,xxxxx,xxxx from districute where entity_id=:id and status='ACTIVE', 其中entity_id是传入的参数。 在反复比较之后,基本上这个地方不太可能出现问题,在API想传入这个特殊字符都不容易。但是一模一样的语句在两边执行结果却不相同。 肯定是某个地方出了问题,我静下来,仔细的分析日志中的sql语句,按照目前的情况来说,只可能在某处修改了数据导致的,从这个查询语句往前排查,最终发现了线索。 在这个查询之前,其中有一步是update操作,语句类似update distribute set xxxx=xxx where distribute_no=:distid 从表面上来看,两个语句的唯一共同之处在于都是基于同一个表。 查看sql语句中对应的变量值,发现在select之前的这步操作已经修改了对应的status值,所以在后续的查询中根据entity_id就匹配不到相应的记录了。 通过数据来说明,就如同下面的情况,我们通过distribute_no修改了status值,再通过status,entity_id来匹配对应的数据行得到的结果就为空,在得到的结果为空后,校验失败,于是事务就回退了。然后下一次调用继续update,select,rollack。 entity_id status distribute_no xxxx 100 ACTIVE 100001 xxxxx 分析了这些之后,问题就一下子明朗多了,不是什么特别的bug,不是什么特别的场景,都是潜意识中自己被误导了。所以大家在排查问题的时候,可能提供给你的信息不是最全面最完整的,我们需要分析去佐证。

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

原文发表时间:2015-01-26

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

运维工程师笔试真题:美团点评 2017 春招真题

21640
来自专栏博客园迁移

日常理解

{ 空 } 1. 什么叫线程安全?servlet是线程安全吗? { 答:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次...

9320
来自专栏AhDung

C#通过获取快捷方式指向目标的小示例触碰WMI

.Net本身没有封装对快捷方式的操作类,所以要在C#中操作快捷方式,需要借助“外力”。市面上常见的方法是通过Windows Script Host Object...

15820
来自专栏我的博客

PHP面试常见问题汇总

1、PHP抽象类和接口的区别? a)接口中不可以声明成员变量(包括类静态变量),但是可以声明类常量。抽象类中可以声明各种类型成员变量,实现数据的封装。 b)...

601100
来自专栏进击的程序猿

orm 系列 之 Eloquent使用2

上一篇介绍了Eloquent的migrations和Scheme Builder功能,本文介绍Eloquent最重要的Model。

10030
来自专栏腾讯Bugly的专栏

那些年,我们一起写过的“单例模式”

本文来自:“天天P图攻城狮”公众号(ttpic_dev) 题记 度娘上对设计模式(Design pattern)的定义是:“一套被反复使用、多数人知晓的、经过分...

48340
来自专栏Golang语言社区

Golang单例模式

单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例且该实例易于外界访问,从而方便对实...

39270
来自专栏进击的程序猿

如何组织PHP中的异常

本文的主题是怎么组织php的异常?在大型项目中异常往往被我们忽略,但是如果前期没有很好的规划好,越到项目后期,重构的成本会越大。

16710
来自专栏Golang语言社区

网游内存数据库的设计(1)

网络游戏的数据变动比较频繁,如果每次数据变动都刷往后端数据库,会导致数据库不负重荷。在游戏逻辑和数据库间提供一层缓冲服务,有利于减轻这重压力. 首先,网络游戏的...

39370
来自专栏PHP在线

2016最新面试题出炉

小编最近面试了一些公司,有上市公司也有创业公司,但是面试题都大同小异,小编凭记忆汇总了这些公司的面试题,希望对同行业的小伙伴有所帮助。

215100

扫码关注云+社区

领取腾讯云代金券