NS系统_设备查询_分页部分失效问题解析

NS系统_设备查询_分页部分失效问题解析

背景交代

功能路径:[标记背景黄色为触发功能点或报错用户]

gggg系统

——设施设备-设施设备综合查询-设备综合查询

-设施设备维护-设备维护

——日常养护-维修养护-维修养护处理(新增_表单_维修对象类型[选设备],选择维修对象[弹出设备列表])

问题代码:FMDao - public void findSblist(DataPageGrid dg, SbssCommonSb sbssCommonSb){

...…省略无关内容

if(StringUtils.isNotBlank(dg.getSort())||StringUtils.isNotBlank(dg.getOrder())) {

                       sqlExceptSelect.append(" order by " + dg.getSort() + " "

                                          + dg.getOrder() + ", t.addtime desc ");

              } else {

                       sqlExceptSelect.append(" order by t.addtime desc ");           

}

...…省略无关内容

}

问题数据:

 

注:设备功能代码只有一套,不同用户有各自的设备数据,通过数据权限过滤数据(本例中涉及:NNN、TTT)

 

现象

设备维护-

NNN:

1~3页数据正常,第四页开始,数据不变化

TTT

         数据展示正常

 

分析

解析思路:

  1. 先判断数据问题?还是功能问题?
  2. 根据背景交代中的注,功能代码共用一套,先“排除”功能问题!
  3. 根据现象中的描述,可发现TTT分页功能正常,故TTT数据正常;同理猜测,NNN数据异常。经大致对比,NNN数据的addtime字段为空,而功能代码中排序字段就是它(当然通过代码中排序字段可直接推测出问题原因)。
  4. 有根据地猜测出问题原因(排序字段为空和字段内容相同的结果应该是一致的,结论是oracleorder by 后跟的字段如果唯一,且字段大部分内容相同,便会触发此现象),下面就开始采取方式验证或处理了;
  5. 验证方式比较简单,将排序字段更换成主键,问题解决。

 

解决方法

代码中排序字段添加主键保底(不考虑数据是否正确情况下,功能均可正常运行[提升系统容差能力])

if(StringUtils.isNotBlank(dg.getSort())||StringUtils.isNotBlank(dg.getOrder())) {

     sqlExceptSelect.append(" order by " + dg.getSort() + " "

         + dg.getOrder() + ", t.addtime desc,t.id");

    } else {

     sqlExceptSelect.append(" order by t.addtime desc,t.id"); 

}

答疑

1、为什么NNNaddtime字段为空,而TTT或其他addtime字段均有值?

(1)TTT或其他的数据来源均通过系统生成(单条新增或批量导入[导入excel])

(2)NNN的数据是通过手工整理的excel数据,复制入库表的,addtime字段类型是TIMESTAMP(6),故在excel中此字段为空(那时批量导入功能还未开发,项目经理要求给出个临时处理方案)

2、为什么oracle  order by  字段 值均相同 会引起分页部分失效的诡异事情?

(1)先来了解下oracle 实现分页的 sql 语句(3层select嵌套)

真实语句:

select *

 from (select row_.*, rownum rownum_

          from (select *

                  from AE_SBSS_COMMON_SB t

                 where 1 = 1

                   and mane like ?

                   and isdel = ?

                   and deptcode in

                       (select distinct (sd.range) as depcode

                          from sys_user su, sys_depart_user sdu, sys_depart sd

                         where su.id = sdu.userid

                           and sd.id = sdu.departid

                           and su.id = ?

                        union

                        select distinct (ydr.dataid) as depcode

                          from sys_user      su,

                               sys_role      sr,

                               sys_user_role sur,

                               yw_data_role  ydr

                         where su.id = sur.userid

                           and sr.id = sur.roleid

                           and ydr.roleid = sr.id

                           and su.id = ?)

                 order by t.addtime desc) row_

         where rownum <= 150) table_alias

 where table_alias.rownum_ >= 141

 

去掉数据权限过滤:

select *

 from (select row_.*, rownum rownum_

          from (select *

                  from AE_SBSS_COMMON_SB t

                 where 1 = 1

                   and mane like ?

                   and isdel = ?

                 order by t.addtime desc) row_

         where rownum <= 150) table_alias

 where table_alias.rownum_ >= 141

(2)填入真实参数,更改分页参数看结果

select rownum_,table_alias.*

 from (select row_.*, rownum rownum_

          from (select *

                  from AE_SBSS_COMMON_SB t

                 where 1 = 1

                   and mane like 'NNN'

                   and isdel = '0'

                 order by t.addtime desc) row_

         where rownum <= 110) table_alias

 where table_alias.rownum_ >= 101

select rownum_,table_alias.*

 from (select row_.*, rownum rownum_

          from (select *

                  from AE_SBSS_COMMON_SB t

                 where 1 = 1

                   and mane like 'NNN'

                   and isdel = '0'

                 order by t.addtime desc) row_

         where rownum <= 120) table_alias

 where table_alias.rownum_ >= 111

看到结果了么?同样的id,rownum_变了。在拿这个字段做条件过滤,不诡异才怪呢。

至于为什么它会在这种情况下变化,这个就得问oracle,可能是bug,可能不是(某种其他机制),还有没有必要在一探究竟,在于你。

select rownum_,table_alias.*

 from (select row_.*, rownum rownum_

          from (select *

                  from AE_SBSS_COMMON_SB t

                 where 1 = 1

                   and mane like 'NNN'

                   and isdel = '0'

                 order by t.addtime desc) row_

         where rownum <= 120) table_alias

 where table_alias.rownum_ >= 101

select rownum_,table_alias.*

 from (select row_.*, rownum rownum_

          from (select *

                  from AE_SBSS_COMMON_SB t

                 where 1 = 1

                   and mane like 'NNN'

                   and isdel = '0'

                 order by t.addtime desc) row_

         where rownum <= 140) table_alias

 where table_alias.rownum_ >= 121

rownum是啥,自行科普吧。

更深入的原因解析,后续等还有必要深究时,再行补录。

参考:https://www.cnblogs.com/xuwl/articles/9177683.html

posted @ 2018-06-13 14:02  探索者-water  阅读(196)  评论(0编辑  收藏  举报