perf: 三方言 Mapper XML SQL 优化(SARG/JOIN/死代码)+ Solon 可空参数修复

SQL 优化(结果契约不变,三方言真实测试库回归通过):
- 删除 bsm getTotalConclusion/getTotalSuggest 死代码(依赖 Oracle 18c
  已移除的 wm_concat,接口未引用,汇总逻辑在应用层)
- SARG 优化 13 处:日期列函数包裹(to_char/CONVERT = 年份)改为
  范围查询,使医院库日期索引可命中(体检结果表逐年增长,
  按身份证查历史接口为主要受益者)
- bsm getResultByIdcardAndYearAll/getItemByPeIdAll:每行标量子查询
  改 LEFT JOIN pe_unit_dict;逗号 join 改 ANSI 写法
- ya getPhyexamStatus/getPeStatusByIdnoAndYear:巨型 CASE 状态位
  表达式从重复计算 6 次提为子查询 status_sum + ISNULL 防 NULL

改写过程修复:
- Oracle TO_DATE('2026','YYYY') 默认当前月首日陷阱(实测复现),
  改拼接 '-01-01' 完整日期
- getResultByIdNoOrPeId 的可空参数在 Solon 下被当必填,
  加 required=false

回归:bsm/nx/ya 三方言年份/日期查询族接口全部通过

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-21 14:12:28 +08:00
co-authored by Claude
parent 545fa38789
commit 15ab717317
4 changed files with 94 additions and 95 deletions
@@ -142,8 +142,8 @@ class OrderApi {
/** 16. 根据 id_code 或 pe_id 和审查年份查询体检报告 */
@Mapping(value = "/getResultByIdNoOrPeId", method = [MethodType.POST])
fun getResultByIdNoOrPeId(
@Param("idNo") idNo: String?,
@Param("peId") peId: String?,
@Param(value = "idNo", required = false) idNo: String?,
@Param(value = "peId", required = false) peId: String?,
@Param("auditYear") auditYear: String,
): Result<List<Map<String, Any?>>> {
if (idNo.isNullOrBlank() && peId.isNullOrBlank()) {
@@ -166,12 +166,8 @@
where PE_ID = #{peId}
and CONCLUSION_TEXT is not null
</select>
<select id="getTotalConclusion" resultType="java.util.HashMap">
select wm_concat(PE_DEPT_NAME || ':' || REPLACE(REPLACE(REPLACE(to_lob(CONCLUSION_TEXT), chr(13) || chr(10), ''), chr(13), ''), chr(10), '') || '###') CONCLUSION_TEXT
from V_PHYEXAM_DEPT_RESULT
where PE_ID = #{peId}
and CONCLUSION_TEXT is not null
</select>
<!-- getTotalConclusion/getTotalSuggest 已删除:原实现依赖 wm_concatOracle 18c 起移除,
且接口未引用);汇总逻辑由 OrderService 基于本文件列表查询在应用层完成 -->
<select id="getSuggest" resultType="java.util.Map">
select PE_ID, PE_VISIT_ID, REC_CONTENT, REPLACE(REPLACE(REPLACE(DBMS_LOB.SUBSTR(GUIDE_CONTENT, 4000, 1), chr(13) || chr(10), ''), chr(13), ''), chr(10), '') GUIDE_CONTENT
@@ -191,17 +187,12 @@
where PE_ID = #{peId}
and GUIDE_CONTENT is not null
</select>
<select id="getTotalSuggest" resultType="java.util.HashMap">
select wm_concat(REC_CONTENT || ':' || REPLACE(REPLACE(REPLACE(GUIDE_CONTENT, chr(13) || chr(10), ''), chr(13), ''), chr(10), '') || '###') GUIDE_CONTENT
from V_PHYEXAM_DIAGNOSIS
where PE_ID = #{peId}
and GUIDE_CONTENT is not null
</select>
<select id="getPeStatusByIdnoAndYear" resultType="java.util.HashMap">
select *
from V_PHYEXAM_PE_STATUS
where ID_NO = #{idNo}
and to_char(PE_PRE_DATE, 'yyyy') = #{year}
and PE_PRE_DATE &gt;= TO_DATE(#{year} || '-01-01', 'YYYY-MM-DD')
and PE_PRE_DATE &lt; ADD_MONTHS(TO_DATE(#{year} || '-01-01', 'YYYY-MM-DD'), 12)
</select>
<select id="getResultByIdcardAndYear" resultType="com.hospital.front.vo.MedicalMiddleResultVo">
select DISTINCT
@@ -215,7 +206,8 @@
to_char( AUDIT_DATE, 'yyyy-mm-dd HH24:mi:ss' ) AUDIT_DATE
from V_PHYEXAM_RESULT
where ID_NO = #{idNo}
and to_char(PE_QUEUE_DATE, 'yyyy') = #{year}
and PE_QUEUE_DATE &gt;= TO_DATE(#{year} || '-01-01', 'YYYY-MM-DD')
and PE_QUEUE_DATE &lt; ADD_MONTHS(TO_DATE(#{year} || '-01-01', 'YYYY-MM-DD'), 12)
</select>
<select id="getResultByIdcardAndYearAll" resultType="com.hospital.front.vo.MedicalMiddleResultVo">
SELECT DISTINCT
@@ -235,7 +227,7 @@
a.id_no,
a.NAME,
b.unit_code,
( SELECT t.unit_name FROM pe_unit_dict t WHERE t.unit_code = b.unit_code ) unit_name,
t.unit_name,
b.pe_queue_date,
b.audit_date,
c.pe_dept_code,
@@ -248,15 +240,14 @@
c.unit,
c.print_context
FROM
pe_master_index a,
pe_visit b,
pe_result_dict c
pe_master_index a
JOIN pe_visit b ON b.pe_id = a.pe_id
JOIN pe_result_dict c ON c.pe_id = b.pe_id AND c.pe_visit_id = b.pe_visit_id
LEFT JOIN pe_unit_dict t ON t.unit_code = b.unit_code
WHERE
a.pe_id = b.pe_id
AND b.pe_id = c.pe_id
AND b.pe_visit_id = c.pe_visit_id
and TO_CHAR(b.audit_date, 'YYYY') = #{year}
and id_no = #{idNo}
b.audit_date &gt;= TO_DATE(#{year} || '-01-01', 'YYYY-MM-DD')
and b.audit_date &lt; ADD_MONTHS(TO_DATE(#{year} || '-01-01', 'YYYY-MM-DD'), 12)
and a.id_no = #{idNo}
) a
</select>
@@ -279,7 +270,8 @@
FROM
V_PHYEXAM_RESULT
WHERE
to_char( AUDIT_DATE, 'yyyy-mm-dd' ) = #{auditDate}
AUDIT_DATE &gt;= TO_DATE(#{auditDate}, 'YYYY-MM-DD')
and AUDIT_DATE &lt; TO_DATE(#{auditDate}, 'YYYY-MM-DD') + 1
</select>
<select id="getItemByPeId" resultType="com.hospital.front.vo.MedicalMiddleResultVo">
@@ -313,7 +305,7 @@
a.id_no,
a.NAME,
b.unit_code,
( SELECT t.unit_name FROM pe_unit_dict t WHERE t.unit_code = b.unit_code ) unit_name,
t.unit_name,
b.pe_queue_date,
b.audit_date,
c.pe_dept_code,
@@ -326,14 +318,12 @@
c.unit,
c.print_context
FROM
pe_master_index a,
pe_visit b,
pe_result_dict c
pe_master_index a
JOIN pe_visit b ON b.pe_id = a.pe_id
JOIN pe_result_dict c ON c.pe_id = b.pe_id AND c.pe_visit_id = b.pe_visit_id
LEFT JOIN pe_unit_dict t ON t.unit_code = b.unit_code
WHERE
a.pe_id = b.pe_id
AND b.pe_id = c.pe_id
AND b.pe_visit_id = c.pe_visit_id
AND b.pe_id= #{peId}
b.pe_id = #{peId}
) a
</select>
@@ -358,7 +348,8 @@
and PE_ID = #{peId}
</if>
and to_char(AUDIT_DATE,'yyyy')=#{auditYear}
and AUDIT_DATE &gt;= TO_DATE(#{auditYear} || '-01-01', 'YYYY-MM-DD')
and AUDIT_DATE &lt; ADD_MONTHS(TO_DATE(#{auditYear} || '-01-01', 'YYYY-MM-DD'), 12)
</where>
</select>
@@ -368,7 +359,8 @@
<if test="idNo != null and idNo != '' ">
and ID_NO = #{idNo}
</if>
and to_char(PE_PRE_DATE,'yyyy') = to_char(SYSDATE,'yyyy')
and PE_PRE_DATE &gt;= TRUNC(SYSDATE, 'YYYY')
and PE_PRE_DATE &lt; ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 12)
</where>
order by PE_PRE_DATE desc
@@ -393,7 +385,8 @@
<if test="idNo != null and idNo != '' ">
and ID_NO = #{idNo}
</if>
and to_char(PE_PRE_DATE,'yyyy') = to_char(SYSDATE,'yyyy')
and PE_PRE_DATE &gt;= TRUNC(SYSDATE, 'YYYY')
and PE_PRE_DATE &lt; ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 12)
</where>
order by PE_PRE_DATE desc
</select>
@@ -214,7 +214,8 @@
V_PHYEXAM_PE_STATUS
WHERE
id_no = #{idNo}
AND CONVERT ( VARCHAR ( 4 ), Pe_pre_date, 23 ) = #{year}
AND Pe_pre_date &gt;= CONVERT(DATETIME, #{year} + '-01-01')
AND Pe_pre_date &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{year} + '-01-01'))
</select>
@@ -233,7 +234,8 @@
<if test="idNo != null and idNo != '' ">
and ID_NO = #{idNo}
</if>
and CONVERT ( VARCHAR ( 4 ), PE_PRE_DATE, 23 ) = CONVERT ( VARCHAR ( 4 ), GETDATE(), 23 )
and PE_PRE_DATE &gt;= CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01')
and PE_PRE_DATE &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01'))
</where>
order by PE_PRE_DATE desc
@@ -251,7 +253,8 @@
<if test="idNo != null and idNo != '' ">
and ID_NO = #{idNo}
</if>
and CONVERT ( VARCHAR ( 4 ), PE_PRE_DATE, 23 ) = CONVERT ( VARCHAR ( 4 ), GETDATE(), 23 )
and PE_PRE_DATE &gt;= CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01')
and PE_PRE_DATE &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01'))
</where>
</select>
@@ -290,7 +293,8 @@
CONVERT(varchar(100),max(AUDIT_DATE),20) AUDIT_DATE
from V_PHYEXAM_RESULT
where ID_NO = #{idNo}
AND CONVERT(varchar(4),AUDIT_DATE,23) = #{year}
AND AUDIT_DATE &gt;= CONVERT(DATETIME, #{year} + '-01-01')
AND AUDIT_DATE &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{year} + '-01-01'))
group by id_no,NAME,PE_ID,UNIT_NAME
</select>
<select id="getResultByIdcardAndYearAll" resultType="com.hospital.front.vo.MedicalMiddleResultVo">
@@ -305,7 +309,8 @@
CONVERT(varchar(100),max(AUDIT_DATE),20) AUDIT_DATE
from V_PHYEXAM_RESULT
where ID_NO = #{idNo}
AND CONVERT(varchar(4),AUDIT_DATE,23) = #{year}
AND AUDIT_DATE &gt;= CONVERT(DATETIME, #{year} + '-01-01')
AND AUDIT_DATE &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{year} + '-01-01'))
group by id_no,NAME,PE_ID,UNIT_NAME
</select>
@@ -320,7 +325,8 @@
CONVERT(varchar(100),max(PE_QUEUE_DATE),20) PE_QUEUE_DATE,
CONVERT(varchar(100),max(AUDIT_DATE),20) AUDIT_DATE
from V_PHYEXAM_RESULT
where CONVERT(varchar(100),AUDIT_DATE,23) = #{auditDate}
where AUDIT_DATE &gt;= CONVERT(DATETIME, #{auditDate})
AND AUDIT_DATE &lt; DATEADD(DAY, 1, CONVERT(DATETIME, #{auditDate}))
group by id_no,NAME,PE_ID,UNIT_NAME
</select>
@@ -376,7 +382,8 @@
and PE_ID = #{peId}
</if>
and CONVERT(varchar(4),AUDIT_DATE,23)=#{auditYear}
and AUDIT_DATE &gt;= CONVERT(DATETIME, #{auditYear} + '-01-01')
and AUDIT_DATE &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{auditYear} + '-01-01'))
</where>
group by id_no,NAME,PE_ID,UNIT_NAME
</select>
@@ -59,32 +59,28 @@
<select id="getPhyexamStatus" resultType="java.util.Map">
SELECT
tjh PE_ID,
xm NAME,
sfzh ID_NO,
dwmc UNIT_NAME,
dwbm DEPARTMENT,
(CONVERT(varchar(100), yyrq, 20)) PE_PRE_DATE,
t.tjh PE_ID,
t.xm NAME,
t.sfzh ID_NO,
t.dwmc UNIT_NAME,
t.dwbm DEPARTMENT,
(CONVERT(varchar(100), t.yyrq, 20)) PE_PRE_DATE,
(
CASE
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '4' THEN
N'审'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '3' THEN
N'初审'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '2' THEN
N'检中'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '1' THEN
N'报道'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '0' THEN
N'预约'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) IS NULL THEN
N'预约'
CASE t.status_sum
WHEN 4 THEN N'终审'
WHEN 3 THEN N'审'
WHEN 2 THEN N'检中'
WHEN 1 THEN N'报道'
WHEN 0 THEN N'预约'
ELSE N'预约'
END
) PE_STATUS
FROM
V_YGTJZT
( SELECT tjh, xm, sfzh, dwmc, dwbm, yyrq,
( ISNULL(bdzt,0) + ISNULL(jczt,0) + ISNULL(cszt,0) + ISNULL(zszt,0) ) status_sum
FROM V_YGTJZT ) t
WHERE
CHARINDEX( ',' + tjh + ',', ',' + #{peIds} + ',' ) >0
CHARINDEX( ',' + t.tjh + ',', ',' + #{peIds} + ',' ) >0
</select>
<select id="getItemList" resultType="java.util.Map">
@@ -205,32 +201,29 @@
</select>-->
<select id="getPeStatusByIdnoAndYear" resultType="java.util.Map">
SELECT
tjh PE_ID,
xm NAME,
sfzh ID_NO,
dwmc UNIT_NAME,
dwbm DEPARTMENT,
(CONVERT(varchar(100), yyrq, 20)) PE_PRE_DATE,
t.tjh PE_ID,
t.xm NAME,
t.sfzh ID_NO,
t.dwmc UNIT_NAME,
t.dwbm DEPARTMENT,
(CONVERT(varchar(100), t.yyrq, 20)) PE_PRE_DATE,
(
CASE
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '4' THEN
N'审'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '3' THEN
N'初审'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '2' THEN
N'检中'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '1' THEN
N'报道'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) = '0' THEN
N'预约'
WHEN ( bdzt + 0+jczt + 0+cszt + 0+zszt + 0 ) IS NULL THEN
N'预约'
CASE t.status_sum
WHEN 4 THEN N'终审'
WHEN 3 THEN N'审'
WHEN 2 THEN N'检中'
WHEN 1 THEN N'报道'
WHEN 0 THEN N'预约'
ELSE N'预约'
END
) PE_STATUS
FROM
V_YGTJZT
WHERE SFZH = #{idNo}
AND CONVERT(varchar(4), YYRQ, 23) = #{year}
( SELECT tjh, xm, sfzh, dwmc, dwbm, yyrq,
( ISNULL(bdzt,0) + ISNULL(jczt,0) + ISNULL(cszt,0) + ISNULL(zszt,0) ) status_sum
FROM V_YGTJZT ) t
WHERE t.SFZH = #{idNo}
AND t.yyrq &gt;= CONVERT(DATETIME, #{year} + '-01-01')
AND t.yyrq &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{year} + '-01-01'))
</select>
<select id="getResultByIdcardAndYear" resultType="com.hospital.front.vo.MedicalMiddleResultVo">
SELECT
@@ -246,7 +239,8 @@
V_TJBGJG
WHERE
SFZH = #{ idNo }
AND CONVERT(varchar(4),SHSJ,23) = #{year}
AND SHSJ &gt;= CONVERT(DATETIME, #{year} + '-01-01')
AND SHSJ &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{year} + '-01-01'))
group by SFZH,XM,TJH,DWMC
</select>
<select id="getResultByIdcardAndYearAll" resultType="com.hospital.front.vo.MedicalMiddleResultVo">
@@ -263,7 +257,8 @@
V_TJBGJG
WHERE
SFZH = #{ idNo }
AND CONVERT(varchar(4),SHSJ,23) = #{year}
AND SHSJ &gt;= CONVERT(DATETIME, #{year} + '-01-01')
AND SHSJ &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{year} + '-01-01'))
group by SFZH,XM,TJH,DWMC
</select>
@@ -286,7 +281,8 @@
FROM
V_TJBGJG
WHERE
CONVERT(varchar(100),shsj,23)= #{auditDate}
shsj &gt;= CONVERT(DATETIME, #{auditDate})
AND shsj &lt; DATEADD(DAY, 1, CONVERT(DATETIME, #{auditDate}))
GROUP BY SFZH,XM,TJH,DWMC
</select>
@@ -342,7 +338,8 @@
and TJH = #{peId}
</if>
and CONVERT(varchar(4),shsj,23)=#{auditYear}
and shsj &gt;= CONVERT(DATETIME, #{auditYear} + '-01-01')
and shsj &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, #{auditYear} + '-01-01'))
</where>
GROUP BY SFZH,XM,TJH,DWMC
</select>
@@ -357,7 +354,8 @@
<if test="idNo != null and idNo != '' ">
and SFZH = #{idNo}
</if>
and CONVERT ( VARCHAR ( 4 ), JCWCSJ, 23 ) = CONVERT ( VARCHAR ( 4 ), GETDATE(), 23 )
and JCWCSJ &gt;= CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01')
and JCWCSJ &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01'))
</where>
order by JCWCSJ desc
@@ -390,7 +388,8 @@
<if test="idNo != null and idNo != '' ">
and SFZH = #{idNo}
</if>
and CONVERT ( VARCHAR ( 4 ), JCWCSJ, 23 ) = CONVERT ( VARCHAR ( 4 ), GETDATE(), 23 )
and JCWCSJ &gt;= CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01')
and JCWCSJ &lt; DATEADD(YEAR, 1, CONVERT(DATETIME, CONVERT(VARCHAR(4), GETDATE(), 23) + '-01-01'))
</where>
</select>