解决部分月份绩效无法显示的问题:timestamp\union al\autocommit等的用法

简介:

  绩效部同事反映部分员工绩效在查询时无法显示,并给出了两个工号。这两个工号对应绩效全部正常审批完成,但在绩效管理模块却无法显示。绩效管理采用分页查询,查询语句为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<!-- 绩效查询集合  -->
     < select  id = "queryList"   resultMap = "PerformanceResultMap"   parameterType = "com.fx.oa.module.per.performance.api.shared.domain.PerformanceEntity" >
         select * from (
         select
         Performance.id,
         f_nd,
         f_khqj,
         f_staffname,
         f_staffid,
         f_bm,
         f_zw,
         f_sqrq,
         f_zf3,
         sum(f_zpf1+f_zpf2+f_zpf3+f_zpf4+f_zpf5+f_zpf9+f_zpf10+f_zpf11+f_zpf12+f_zpf13+f_zpf17+f_zpf18+f_zpf19+f_zpf20+f_zpf21)f_dqjxfs,
         sum(f_df1+f_df2+f_df3+f_df4+f_df5+f_df9+f_df10+f_df11+f_df12+f_df13+f_df17+f_df18+f_df19+f_df20+f_df21)f_syfszh,
         f_txrzjzgname,
         f_jxzzdf,
         f_jxdj,
         f_jxxs,
         f_zf1,
         f_zf2,
         releaseDate,
         zjzg,
         activityName,
        processExecutionId,
       dqspr,
       userNameandTaskid ,
        sortno, '普通'jxlx  from (SELECT 
         < include  refid = "PerformanceAll_flow_column" />
         < include  refid = "jx_tabale" />
         < include  refid = "glflow" />
         < include  refid = "select_Where" />
         < include  refid = "sql_group_by" />
         ) Performance
         < include  refid = "out_select_Where" /> 
         group by id
          union all
         select Performance.* from (
             SELECT '1'as id,
                         f_nd,
f_khqj,
f_staffname,
f_staffid,
f_bm,
f_zw,
f_sqrq,
f_zf3,
f_dqjxfs,
f_syfszh,
f_txrzjzgname,
f_jxzzdf,
f_jxdj,
f_jxxs,
f_zf1,
f_zf2,
releaseDate,
zjzg,
activityName,
processExecutionId,
dqspr,
userNameandTaskid,
sortno,
jxlx
 
                     FROM
                         t_per_his_performance Performance
                     )Performance LEFT JOIN tree_node tree ON Performance.f_staffid = tree.id
          < include  refid = "out_select_Where" />
        < if  test = "isAdmin !='' and isAdmin  != null" >
             <![CDATA[
              and tree.leftId >= (select leftId from tree_node treenode where treenode.id= #{currentUserStaffid}) and  tree.rightId <= (select rightId from tree_node treenode where treenode.id=#{currentUserStaffid})
                 ]]>
             </ if >
            ) Performance where  Performance.id !=0  
         < include  refid = "sql_order_by" />
     </ select >

   语句中包含一个union,主要用于查询历史绩效(历史绩效指与绩效表结构完成相同,但主要用于存储OA上线前在moss上所填写的绩效数据,用于员工自行查询)。

   截取的sql语句如下: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  select  Performance.id  from  ( SELECT 
         Performance.id,
         f_nd,
         f_khqj,
         f_staffname,
         f_staffid,
         f_bm,
         f_zw1  as  f_zw,
         f_sqrq,
         f_zf3,
         f_dqjxfs,
         f_kpi,
         f_gs,
         ifnull(f_df1,0)f_df1,
         ifnull(f_df2,0)f_df2,
         ifnull(f_df3,0)f_df3,
         ifnull(f_df4,0)f_df4,
         ifnull(f_df5,0)f_df5,
         ifnull(f_df9,0)f_df9,
         ifnull(f_df10,0)f_df10,
         ifnull(f_df11,0)f_df11,
         ifnull(f_df12,0)f_df12,
         ifnull(f_df13,0)f_df13,
         ifnull(f_df17,0)f_df17,
         ifnull(f_df18,0)f_df18,
         ifnull(f_df19,0)f_df19,
         ifnull(f_df20,0)f_df20,
         ifnull(f_df21,0)f_df21,
         ifnull(f_zpf1,0)f_zpf1,
         ifnull(f_zpf2,0)f_zpf2,
         ifnull(f_zpf3,0)f_zpf3,
         ifnull(f_zpf4,0)f_zpf4,
         ifnull(f_zpf5,0)f_zpf5,
         ifnull(f_zpf9,0)f_zpf9,
         ifnull(f_zpf10,0)f_zpf10,
         ifnull(f_zpf11,0)f_zpf11,
         ifnull(f_zpf12,0)f_zpf12,
         ifnull(f_zpf13,0)f_zpf13,
         ifnull(f_zpf17,0)f_zpf17,
         ifnull(f_zpf18,0)f_zpf18,
         ifnull(f_zpf19,0)f_zpf19,
         ifnull(f_zpf20,0)f_zpf20,
         ifnull(f_zpf21,0)f_zpf21,
         f_txrzjzgname,
         f_jxzzdf,
         f_jxdj,
         f_jxxs,
         f_zf1,
         f_zf2,
         Performance.releaseDate,
         zjzginfo.staffName  AS  zjzg,
         case  when  exec .status= '2'  then  '结束'  when  ISNULL (activityName)=1  then  '绩效填写'  else  task.activityName  END  activityName,
         exec .id  as  processExecutionId,
       GROUP_CONCAT( distinct  staff.staffname)  as  dqspr,
       CONCAT( '[' ,GROUP_CONCAT( distinct  CONCAT( '{userName:' , '"' ,task.createUserCode, '"' , ',taskid:' , '"' ,task.taskId, '"' , '}' )), ']' as  userNameandTaskid ,
       case 
       when  activityName= 'start1'  then 
       when  activityName= '工作行为考核人确认'  then 
       when  activityName= '重新填写'  then 
       when  activityName= '填写人自评' 
       then  when  activityName= '考核人评估' 
       then  else  END  sortno  
         , '普通'  as  jxlx  from  T_DYMC_20150211170947  Performance 
         left  join  tree_node tree  on  Performance.f_staffid=tree.id
     left  join  t_bpm_process_execution  exec  on   Performance.id= exec .pkValue 
     left  join  t_bpm_process_define process  on  process.id= exec .processDefineId
     left  join  t_bpm_process_task task  on  exec .id=task.processExecutionId  and  task.status= '0'
     left  join  t_per_staffinfo staff  on  task.createUserCode=staff.staffcode  and  staffStatus= 'zz'
     LEFT  JOIN  t_per_staffinfo zjzg  ON  Performance.f_staffid = zjzg.staffid
     LEFT  JOIN  t_per_staffinfo zjzginfo  ON  zjzg.directLeaderCode = zjzginfo.staffid 
where  tree.leftId >= ( select  leftId  from  tree_node treenode  where  treenode.id=  'FX004613' and   tree.rightId <= ( select  rightId  from  tree_node treenode  where  treenode.id=  'FX004613' )
GROUP  BY  pkValue ) Performance  where  Performance.f_staffName =  '潘宇' 
and   Performance.id != 0

   该语句经走读并未发现明显问题。

   在数据库中进行比较,发现以下问题

  1. id(uuid)规律与其他明显不同;

  2. releaseDate为空;

    wKioL1ebFgrSWXr2AAAoPYtrxr4840.png-wh_50

    releaseDate用于最新更新时间,做为锁并行并发控制;之前有一篇博文介绍会签并发控制的。

    releaseDate是timestamp,对timeStamp的了解是1.有确定的表示时间的范围;2.相当于一个trigger,会随着数据变化取当前时间;3.mysql允许存在多个timestamp的属性,如有多个只有第一个可以正常更新当前时间;

参看:mysql之TIMESTAMP(时间戳)用法详解

  查看创建表的语句,只保留releaseDate的创建

1
2
3
4
5
show  create  table  t_dymc_20150211170947
 
..
   `releaseDate`  timestamp  NULL  DEFAULT  NULL  ON  UPDATE  CURRENT_TIMESTAMP ,
..

releaseDate:第一,允许空,第二,创建时默认为空,第三,每次更新均自动更新为当前时间;

   查询数据库的commit机制

1
show engine innodb status  like  '%commit%'

   所有的事务提交都是autocommit,考虑到可能出现这样的问题,即在审批时,表单表可能被锁,导致该事务未提交成功,而其他表的更新均成功,所以代码中如未对事务做准确的控制,这种情况是可能出现的。但如接受这思路,就无法解释三次提交均锁表的情况。

   使用如下语句查看lock情况

1
show status  like  ‘%lock%’

   查找锁表,未发现问题。

   由于以上主要针对releaseDate为什么为空和id的创建规律为何突变。由于反复确认两个问题无果,以及两个问题均未导致流程的审批出现明显问题。所以,解决方向变为主攻查询语句。

   经进一步确认,该查询是个分页查询,结果条数与下方显示的总数条数不同,始终少一,少的就应该是问题数据;使用compare对queryList和queryCount进行比较,发现两者不同之处有四;

  1. querylist在将流程数据和历史数据进行联合时使用union,queryCount使用的是unionAll。该思路一度让我对之前对两者最基本区别的认知产生动摇。实际上经过测试也并不是union/unionAll导致。参看:union和union all的区别

  2. queryList多了一个where id != 0该代码由其他已离职同事编写,用意不明(可能是因为在查询历史数据时,返回的Id不是其真正的id,而是统一为"0",这段代码也莫名其妙);

  3. queryList多了一个order;

  4. queryList中在一个返回属值“pxtl”前多了两个汉字,两个汉字也未加""

    分别对以上进行测试,发现只有2去掉之后问题不再出现

  经测试,发现sql有如下规律

   在sql中,当id为字符串且首字符是字母时,id !=数字0,当id的首字母为数字时,id=数字0。经确认,6-7日晚至6-8日填写的所有绩效,其id的生成规律均与其他明显不同;首字符为f,其他首字符为2,所以查询不到。目前已将id!=0拿掉,经测试问题解决。

  经一步查询id开头非数字的,发现均在6月7日至6月8日,该问题产生原因目前不明。

 





     本文转自 gaochaojs 51CTO博客,原文链接:http://blog.51cto.com/jncumter/1831804,如需转载请自行联系原作者

相关文章
|
8月前
|
SQL Oracle 关系型数据库
sql中sysdate 和 current_date 的区别及to_char( tv_date, ‘YYYY-MM-DD‘)当天时间与数据库时间的格式转换与比较
在oracle中current_date与sysdate都是显示当前系统时间, 其结果基本相同,但是有三点区别: 1. current_date返回的是当前会话时间,而sysdate返回的是服务器时间; 2. current_date有时比sysdate快一秒,这可能是四舍五入的结果; 3. 如果修改当前会话的时区,比如将中国的时区为东八区,修改为东九区,则current_date显示的时间为东九区时间, 根据东加西减的原则,current_date应该比sysdate快一小时。
398 0
sql中sysdate 和 current_date 的区别及to_char( tv_date, ‘YYYY-MM-DD‘)当天时间与数据库时间的格式转换与比较
|
存储 SQL 关系型数据库
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(上)
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(上)
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(上)
|
存储 SQL 安全
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(中)
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(中)
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(中)
|
存储 SQL 关系型数据库
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(下)
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(下)
【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(下)
SAP QM执行事务代码QE23为检验批录入结果,报错-No selected set exists for the inspection point 200 or plant NMDC-
SAP QM执行事务代码QE23为检验批录入结果,报错-No selected set exists for the inspection point 200 or plant NMDC-
SAP QM执行事务代码QE23为检验批录入结果,报错-No selected set exists for the inspection point 200 or plant NMDC-
Sql:成功解决将sql输出的datetime时间格式转为常规格式
Sql:成功解决将sql输出的datetime时间格式转为常规格式
|
Web App开发 JavaScript 前端开发