子集字段编辑后,自动更新主集字段的值
业务场景:主集A字段的值,根据子集“职称等级”、“是否聘任”算出来的,但是模板上不支持编辑公式让子集“职称等级”、“是否聘任” 字段去影响主集的A字段。
解决方法:1、写一张视图,算出子集“职称等级”、“是否聘任”字段编辑后,A字段应该的值。
SQL如下(得到人员的主键与A字段应该的值):
select
distinct
A.pk_psndoc,
case when a.sex=1 then to_char(add_months(to_date(A.DANL,'yyyy-mm-dd'),720),'YYYY-MM-DD')
when a.sex=2 and (
A.ZW in('领导班子','中干正职','中干副职')
or A.ZCDJ in ('高级职称(正高)','高级职称(副高)','高级技师(一级)/中级职称')
or A.SFGL=1) then to_char(add_months(to_date(A.DANL,'yyyy-mm-dd'),660),'YYYY-MM-DD')
else to_char(add_months(to_date(A.DANL,'yyyy-mm-dd'),600),'YYYY-MM-DD')
end TXRQ
from
(
select
tableJob.pk_psndoc as pk_psndoc,--人员主键
bd_psndoc.sex as sex,--性别
bd_psndoc.glbdef15 as DANL,--档案年龄
om_job.jobname as ZW,--职务
ZCDJ.name as ZCDJ,--职称等级
bd_psndoc.glbdef20 as SFGL--是否管理
from bd_psndoc
LEFT OUTER JOIN (
select pk_psnjob,pk_psndoc,begindate,pk_job
FROM (select
T.*,
ROW_NUMBER() OVER(PARTITION BY T.pk_psndoc ORDER BY T.begindate DESC) FLAG
FROM (
select pk_psnjob,pk_psndoc,begindate,pk_job from hi_psnjob where hi_psnjob.ismainjob='Y' order by begindate desc
)T
) TMP
WHERE TMP.FLAG = 1
)tableJob on tableJob.pk_psndoc=bd_psndoc.pk_psndoc
LEFT OUTER JOIN om_job on om_job.pk_job=tableJob.pk_job
LEFT OUTER JOIN (
--第一次这么写的,后面遇到一个经典问题,见后文。
select pk_psndoc,titlerank,recordnum from hi_psndoc_title where hi_psndoc_title.tiptop_flag='Y'
)tabletitle on tabletitle.pk_psndoc =tableJob.pk_psndoc
LEFT OUTER JOIN bd_defdoc ZCDJ on ZCDJ.pk_defdoc=tabletitle.titlerank
) A
2、写一个触发器,当子集变化后,执行触发器,更新A字段的值为视图里面的值。
过程中遇到的一个经典问题:
当子集有多行第一行为N,第二行为Y的时候,点击修改,第一行改为Y,第二行改为N的时候,居然报“子查询返回了多行的错误”,意思是“子集有人存在多行为Y了,但是系统限制了同一个人不能多行为Y”这个时候找了很久,最后原因是:第一行改为Y,第二行改为N的时候,程序先执行的第一行改为Y,然后进行触发,这个时候对于这个人来书,第一行和第二行都为Y了,直接报错。!
分析原因:触发器执行顺序没有搞清楚,正常顺序为:子集第一行更新->触发器执行->然后第二行数据更新....
处理思路:既然第一行更新为Y了,在第二行更新为N之前触发器执行的时候,第一、二行都是Y,则处理一下,按照顺序排列,一个人只取一行就行了。
select pk_psndoc,titlerank,recordnum from hi_psndoc_title where hi_psndoc_title.tiptop_flag='Y'
改为:
select pk_psndoc,titlerank
FROM (select
T.*,
ROW_NUMBER() OVER(PARTITION BY T.pk_psndoc ORDER BY T.recordnum DESC) FLAG
FROM (
select pk_psndoc,titlerank,recordnum from hi_psndoc_title where hi_psndoc_title.tiptop_flag='Y'
order by recordnum desc
)T
) TMP
WHERE TMP.FLAG = 1
最终的视图为:
select
distinct
A.pk_psndoc,
case when a.sex=1 then to_char(add_months(to_date(A.DANL,'yyyy-mm-dd'),720),'YYYY-MM-DD')
when a.sex=2 and (
A.ZW in('领导班子','中干正职','中干副职')
or A.ZCDJ in ('高级职称(正高)','高级职称(副高)','高级技师(一级)/中级职称')
or A.SFGL=1) then to_char(add_months(to_date(A.DANL,'yyyy-mm-dd'),660),'YYYY-MM-DD')
else to_char(add_months(to_date(A.DANL,'yyyy-mm-dd'),600),'YYYY-MM-DD')
end TXRQ
from
(
select
tableJob.pk_psndoc as pk_psndoc,--人员主键
bd_psndoc.sex as sex,--性别
bd_psndoc.glbdef15 as DANL,--档案年龄
om_job.jobname as ZW,--职务
ZCDJ.name as ZCDJ,--职称等级
bd_psndoc.glbdef20 as SFGL--是否管理
from bd_psndoc
LEFT OUTER JOIN (
select pk_psnjob,pk_psndoc,begindate,pk_job
FROM (select
T.*,
ROW_NUMBER() OVER(PARTITION BY T.pk_psndoc ORDER BY T.begindate DESC) FLAG
FROM (
select pk_psnjob,pk_psndoc,begindate,pk_job from hi_psnjob where hi_psnjob.ismainjob='Y' order by begindate desc
)T
) TMP
WHERE TMP.FLAG = 1
)tableJob on tableJob.pk_psndoc=bd_psndoc.pk_psndoc
LEFT OUTER JOIN om_job on om_job.pk_job=tableJob.pk_job
LEFT OUTER JOIN (
--select pk_psndoc,titlerank,recordnum from hi_psndoc_title where hi_psndoc_title.tiptop_flag='Y'
select pk_psndoc,titlerank
FROM (select
T.*,
ROW_NUMBER() OVER(PARTITION BY T.pk_psndoc ORDER BY T.recordnum DESC) FLAG
FROM (
select pk_psndoc,titlerank,recordnum from hi_psndoc_title where hi_psndoc_title.tiptop_flag='Y'
order by recordnum desc
)T
) TMP
WHERE TMP.FLAG = 1
)tabletitle on tabletitle.pk_psndoc =tableJob.pk_psndoc
LEFT OUTER JOIN bd_defdoc ZCDJ on ZCDJ.pk_defdoc=tabletitle.titlerank
) A
经验证,程序完美执行。