好坑的sql_mode--设置的不同导致查询获得的结果不同
昨天下班回到家里之后,接到单位同事打过来的电话,描述的情况如下 “ 我们正在上一个系统,同样的数据,同样的sql,在总部的数据库环境里面查询获得的是正确的结果,结果集是五条,但在分部数据库里面,查出来的结果只有两条数据,跟预想的结果不一样,少了三条数据 ,然后特别的说明了一下环境差异, 总部使用的版本是mysql 5.6.21, 而分部使用的数据库版本是您推荐的mysql 5.6.30(实际上,这也是合作公司给我们同事反馈的结果,因为该系统由外部的软件公司开发,上线部署等都由其支持) “,听到最后一句话,看起来貌似躺枪了---- mysql 5.6.30的版本是作者推荐的,是mysql5.6的最新版本。难道是因为版本差异导致? 但对于疑问,本人认为可能性只有1%,因为觉得高的小版本应该是解决了更多的问题,而带来问题的可能是会非常小。
how can 1 do ?
已经到家,再返回单位?算了吧,路上花的时间有可能让我已经把问题解决了。决定先让合作公司的人把原始数据还有执行的sql发邮件给我,我先在家里看看。
很快收到了数据跟sql ,因为我个人电脑上也没有装mysql 5.6.30,所以不能在5.6.30上进行验证,只有装载虚拟机上的最新的mysql 5.7.12版本。因为本来就觉得是小版本差异导致查询结果差异的可能性极低 。加上从官网上下载mysql 5.6.30,下载速度不够快,得花半个小时才能下载完成, 所以决定先在5.7.12上找原因。
把数据灌进数据库里面花了一点时间,然后执行sql验证,发现果然是5条数据 。 但在分部的数据库里面,只能查出2条数据,why ? 但很快,意识到分部的数据库是分部科技人员或者合作商自己装的, 可能使用的大多数参数都是默认值,最可能影响sql执行结果或许是sql_mode的设置。
所以,立马将sql_mode 修改成默认值,然后执行sql ,结果如下(表名跟结果,以及关键查询条件都做了脱敏处理):
mysql> set sql_mode='';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SELECT * FROM table_a l
-> LEFT JOIN table_b a ON a.`APPLY_ID` = l.`APPLY_ID`
-> LEFT JOIN table_c m ON a.`INST_NO` = m.`INST_NO`
-> WHERE l.`ASSIGN_TYPE` = 3 AND l.`ASSIGN_TO` IN (
-> SELECT CAST(u.`ROLE_ID` AS CHAR) FROM table_d u
-> WHERE u.`USER_ID` IN (SELECT p.`UID` FROM table_e p
-> WHERE p.`INST_NO` = a.`INST_NO`
-> AND p.`POST_TYPE` = 'YFSD_' || CAST(a.APPLY_TYPE AS CHAR)
-> AND p.`ROLE_ID` = l.`ASSIGN_TO`
-> AND p.`UID` = '***************'
-> ))
-> ;
+--------+-----------------------------+----------+------------+-----------------+--------------+
| JOB_ID | JOB_NAME | JOB_FLAG | JOB_STATUS | STATUS_NAME | NEXT_OP |
+--------+-----------------------------+----------+------------+-----------------+--------------+
| 209 | 房产抵押贷款申请620 | LOAN | 2 | 申请已分配 | 等待受理 |
| 211 | 房产抵押贷款申请622 | LOAN | 2 | 申请已分配 | 等待受理 |
+--------+-----------------------------+----------+------------+-----------------+--------------+
2 rows in set (0.10 sec)
mysql> exit
如图:
出现了两条结果,跟合作商的研发人员反馈的现象一致。到此,问题也就解决了。 Mysql 5.6.30 下载仍然在继续,进度条显示42%。
问题导致解决了,但是是什么原因,导致了sql_mode为空时,丢失了3条数据的呢? 为什么是这3条数据 ?丢失的三条数据有何特征 ?
因为sql能够正确执行且不报出任何错误,所以一直在数据上找瑕疵,猜测是发生某些转换导致了结果集的不正确。仔细比对数据之后,没有任何发现。
再后来,仔细review sql语句,不是有个|| 管道符吗 ? 是不是这样造成的, 再结合的验证库中的标准的sql_mode 中含有“pipes_as_concat ", 是不是不指定pipes_as_concat , 就不支持|| 做为连接符。 但是,不支持不该报个错误信息莫? 居然还能出结果,只不过是少了3条?
如是, 将sql_mode 仅设置成”pipes_as_concat “ ,然后一测, 出来正常的结果了。 这不是坑人莫,不支持也得报个一下错误,不是莫?
- Cannot resolve the collation conflict between "Chinese_PRC_CI_AS" and "SQL_L及由于排序规则不同导致查询结果为空的问题
- sql中外连接条件位置不同导致的查询结果不过
- Cannot resolve the collation conflict between "Chinese_PRC_CI_AS" and "SQL_L及由于排序规则不同导致查询结果为空的问题
- 【转】PL/SQL编辑数据"这些查询结果不可更新,请包括ROWID或使用SELECT...FOR UPDATE获得可更新结果"处理
- 注意Transact-SQL中Case函数的两种用法导致不同的结果集
- 数据库-使用查询到的不同字段的两条SQL的结果进行筛选查询
- SQL SERVER 2000 的企业管理器与查询分析器对于同一SQL语句有两个不同查询结果!
- SQL入门 7 8 9 10 11 12 从查询中获得有效的结果
- 有关在ibatis中动态拼写SQL,查询多次后结果不同的问题
- ThinkPHP的sql_mode的默认设置,导致无效信息被插入
- Hibernate查询之SQL查询,查询结果用new新对象的方式接受,hql查询,通过SQL查询的结果返回到一个实体中,查询不同表中内容,并将查到的不同表中的内容放到List中
- MySQL 5.7 sql_mode设置 分组查询报错
- 解决SQL查询,in条件参数为带逗号的字符串而导致查询结果错误
- Hibernate查询之SQL查询,查询结果用new新对象的方式接受,hql查询,通过SQL查询的结果返回到一个实体中,查询不同表中内容,并将查到的不同表中的内容放到List中
- SQL一次性查询一个字段不同条件下的统计结果
- sql 查询结果为null的设置默认数据
- PL/SQL编辑数据"这些查询结果不可更新,请包括ROWID或使用SELECT...FOR UPDATE获得可更新结果"处理
- 如何建立索引,提高查询速度。 ---- 人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的 性能差异,这种性能差异在大型的或是复杂的数据库环境中
- SQL查询结果集游标循环获得行数据
- 不清楚为什么这两个查询结果为什么不同?oracle sql