|
|
|
|
@ -0,0 +1,396 @@
|
|
|
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
|
|
|
<!DOCTYPE mapper
|
|
|
|
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
|
|
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
|
|
|
<mapper namespace="org.dromara.dms.mapper.DmsReportOeeMapper">
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
OEE 综合效率报表 SQL
|
|
|
|
|
为什么手写 XML:KPI/趋势查询涉及聚合函数、CASE WHEN、GROUP BY 粒度切换,
|
|
|
|
|
MPJ Lambda 表达力不够,手写 SQL 更清晰可控
|
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
<!-- ========== 共享 WHERE 片段 ========== -->
|
|
|
|
|
<sql id="oeeWhere">
|
|
|
|
|
<if test="bo.startDate != null and bo.endDate != null">
|
|
|
|
|
AND t.stat_date BETWEEN #{bo.startDate} AND #{bo.endDate}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.workshopId != null">
|
|
|
|
|
AND t.workshop_id = #{bo.workshopId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.workshopName != null and bo.workshopName != ''">
|
|
|
|
|
AND t.workshop_name LIKE '%' + #{bo.workshopName} + '%'
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.classTeamId != null">
|
|
|
|
|
AND t.class_team_id = #{bo.classTeamId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.classTeamName != null and bo.classTeamName != ''">
|
|
|
|
|
AND t.class_team_name LIKE '%' + #{bo.classTeamName} + '%'
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.shiftId != null">
|
|
|
|
|
AND t.shift_id = #{bo.shiftId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.shiftName != null and bo.shiftName != ''">
|
|
|
|
|
AND t.shift_name LIKE '%' + #{bo.shiftName} + '%'
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.machineId != null">
|
|
|
|
|
AND t.machine_id = #{bo.machineId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="bo.machineName != null and bo.machineName != ''">
|
|
|
|
|
AND t.machine_name LIKE '%' + #{bo.machineName} + '%'
|
|
|
|
|
</if>
|
|
|
|
|
</sql>
|
|
|
|
|
|
|
|
|
|
<!-- ========== 明细分页查询 ========== -->
|
|
|
|
|
<select id="selectOeePage" resultType="org.dromara.dms.domain.vo.DmsReportOeeVo">
|
|
|
|
|
SELECT
|
|
|
|
|
t.report_id AS reportId,
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-MM-dd') AS statDate,
|
|
|
|
|
t.workshop_id AS workshopId,
|
|
|
|
|
t.class_team_id AS classTeamId,
|
|
|
|
|
t.shift_id AS shiftId,
|
|
|
|
|
t.machine_id AS machineId,
|
|
|
|
|
t.workshop_name AS workshopName,
|
|
|
|
|
t.class_team_name AS classTeamName,
|
|
|
|
|
t.shift_name AS shiftName,
|
|
|
|
|
t.machine_name AS machineName,
|
|
|
|
|
t.output_qty AS outputQty,
|
|
|
|
|
t.qualified_qty AS qualifiedQty,
|
|
|
|
|
t.ideal_cycle_time_sec AS idealCycleTimeSec,
|
|
|
|
|
t.run_hours AS runHours,
|
|
|
|
|
t.standby_hours AS standbyHours,
|
|
|
|
|
t.fault_hours AS faultHours,
|
|
|
|
|
t.shutdown_hours AS shutdownHours,
|
|
|
|
|
t.debug_hours AS debugHours,
|
|
|
|
|
t.total_hours AS totalHours,
|
|
|
|
|
t.uptime_rate AS uptimeRate,
|
|
|
|
|
t.overall_efficiency AS overallEfficiency,
|
|
|
|
|
t.runtime_efficiency AS runtimeEfficiency,
|
|
|
|
|
t.availability_rate AS availabilityRate,
|
|
|
|
|
t.performance_rate AS performanceRate,
|
|
|
|
|
t.quality_rate AS qualityRate,
|
|
|
|
|
t.oee_rate AS oeeRate,
|
|
|
|
|
t.teep_rate AS teepRate
|
|
|
|
|
FROM dms_report_device_efficiency t
|
|
|
|
|
WHERE 1 = 1
|
|
|
|
|
<include refid="oeeWhere"/>
|
|
|
|
|
ORDER BY t.stat_date DESC, t.machine_name ASC
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- ========== 导出明细(不分页) ========== -->
|
|
|
|
|
<select id="selectOeeList" resultType="org.dromara.dms.domain.vo.DmsReportOeeVo">
|
|
|
|
|
SELECT
|
|
|
|
|
t.report_id AS reportId,
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-MM-dd') AS statDate,
|
|
|
|
|
t.workshop_id AS workshopId,
|
|
|
|
|
t.class_team_id AS classTeamId,
|
|
|
|
|
t.shift_id AS shiftId,
|
|
|
|
|
t.machine_id AS machineId,
|
|
|
|
|
t.workshop_name AS workshopName,
|
|
|
|
|
t.class_team_name AS classTeamName,
|
|
|
|
|
t.shift_name AS shiftName,
|
|
|
|
|
t.machine_name AS machineName,
|
|
|
|
|
t.output_qty AS outputQty,
|
|
|
|
|
t.qualified_qty AS qualifiedQty,
|
|
|
|
|
t.ideal_cycle_time_sec AS idealCycleTimeSec,
|
|
|
|
|
t.run_hours AS runHours,
|
|
|
|
|
t.standby_hours AS standbyHours,
|
|
|
|
|
t.fault_hours AS faultHours,
|
|
|
|
|
t.shutdown_hours AS shutdownHours,
|
|
|
|
|
t.debug_hours AS debugHours,
|
|
|
|
|
t.total_hours AS totalHours,
|
|
|
|
|
t.uptime_rate AS uptimeRate,
|
|
|
|
|
t.overall_efficiency AS overallEfficiency,
|
|
|
|
|
t.runtime_efficiency AS runtimeEfficiency,
|
|
|
|
|
t.availability_rate AS availabilityRate,
|
|
|
|
|
t.performance_rate AS performanceRate,
|
|
|
|
|
t.quality_rate AS qualityRate,
|
|
|
|
|
t.oee_rate AS oeeRate,
|
|
|
|
|
t.teep_rate AS teepRate
|
|
|
|
|
FROM dms_report_device_efficiency t
|
|
|
|
|
WHERE 1 = 1
|
|
|
|
|
<include refid="oeeWhere"/>
|
|
|
|
|
ORDER BY t.stat_date DESC, t.machine_name ASC
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- ========== KPI 卡片聚合(一次扫描 6 标量) ========== -->
|
|
|
|
|
<select id="selectOeeKpi" resultType="org.dromara.dms.domain.vo.DmsReportOeeKpiVo">
|
|
|
|
|
SELECT
|
|
|
|
|
COUNT(DISTINCT t.machine_id) AS deviceCount,
|
|
|
|
|
AVG(t.oee_rate) AS avgOee,
|
|
|
|
|
AVG(t.availability_rate) AS avgA,
|
|
|
|
|
AVG(t.performance_rate) AS avgP,
|
|
|
|
|
AVG(t.quality_rate) AS avgQ,
|
|
|
|
|
-- 红灯数:OEE 低于字典阈值的设备数;
|
|
|
|
|
-- 为什么先物化阈值:SQL Server 禁止在 SUM() 内部使用包含子查询的表达式。
|
|
|
|
|
SUM(CASE WHEN t.oee_rate < threshold.red_max THEN 1 ELSE 0 END) AS redCount
|
|
|
|
|
FROM dms_report_device_efficiency t
|
|
|
|
|
CROSS JOIN (
|
|
|
|
|
SELECT ISNULL((
|
|
|
|
|
SELECT TOP 1 TRY_CAST(dict_value AS DECIMAL(18,6))
|
|
|
|
|
FROM sys_dict_data
|
|
|
|
|
WHERE tenant_id = '000000' AND dict_type = 'dms_oee_level' AND dict_label = 'red'
|
|
|
|
|
ORDER BY dict_sort ASC, dict_code ASC
|
|
|
|
|
), 0.6) AS red_max
|
|
|
|
|
) threshold
|
|
|
|
|
WHERE 1 = 1
|
|
|
|
|
<include refid="oeeWhere"/>
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- ========== 趋势图数据(按日/周/月聚合) ========== -->
|
|
|
|
|
<!--
|
|
|
|
|
granularity 白名单校验在 Service 层完成,XML 直接使用,安全可拼接
|
|
|
|
|
为什么用 choose/when:SQL Server 的 GROUP BY 需要与 SELECT 表达式一致,
|
|
|
|
|
动态粒度只能用动态 SQL 实现
|
|
|
|
|
-->
|
|
|
|
|
<select id="selectOeeTrend" resultType="org.dromara.dms.domain.vo.DmsReportOeeTrendVo">
|
|
|
|
|
SELECT
|
|
|
|
|
<choose>
|
|
|
|
|
<when test="granularity == 'week'">
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-') + CAST(DATEPART(ISO_WEEK, t.stat_date) AS VARCHAR) AS periodLabel
|
|
|
|
|
</when>
|
|
|
|
|
<when test="granularity == 'month'">
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-MM') AS periodLabel
|
|
|
|
|
</when>
|
|
|
|
|
<otherwise>
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-MM-dd') AS periodLabel
|
|
|
|
|
</otherwise>
|
|
|
|
|
</choose>,
|
|
|
|
|
AVG(t.availability_rate) AS availabilityRate,
|
|
|
|
|
AVG(t.performance_rate) AS performanceRate,
|
|
|
|
|
AVG(t.quality_rate) AS qualityRate,
|
|
|
|
|
AVG(t.oee_rate) AS oeeRate
|
|
|
|
|
FROM dms_report_device_efficiency t
|
|
|
|
|
WHERE 1 = 1
|
|
|
|
|
<include refid="oeeWhere"/>
|
|
|
|
|
GROUP BY
|
|
|
|
|
<choose>
|
|
|
|
|
<when test="granularity == 'week'">
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-') + CAST(DATEPART(ISO_WEEK, t.stat_date) AS VARCHAR)
|
|
|
|
|
</when>
|
|
|
|
|
<when test="granularity == 'month'">
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-MM')
|
|
|
|
|
</when>
|
|
|
|
|
<otherwise>
|
|
|
|
|
FORMAT(t.stat_date, 'yyyy-MM-dd')
|
|
|
|
|
</otherwise>
|
|
|
|
|
</choose>
|
|
|
|
|
ORDER BY periodLabel ASC
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
OEE 扩展列上线前置检查。
|
|
|
|
|
为什么先查元数据:缺列时直接查询业务 SQL 会变成 BadSqlGrammarException,
|
|
|
|
|
用户看不到可执行的处理动作;这里提前给出明确的升级脚本提示。
|
|
|
|
|
-->
|
|
|
|
|
<select id="selectMissingOeeColumns" resultType="java.lang.String">
|
|
|
|
|
SELECT v.column_name
|
|
|
|
|
FROM (VALUES
|
|
|
|
|
('qualified_qty'),
|
|
|
|
|
('ideal_cycle_time_sec'),
|
|
|
|
|
('availability_rate'),
|
|
|
|
|
('performance_rate'),
|
|
|
|
|
('quality_rate'),
|
|
|
|
|
('oee_rate'),
|
|
|
|
|
('teep_rate')
|
|
|
|
|
) AS v(column_name)
|
|
|
|
|
WHERE NOT EXISTS (
|
|
|
|
|
SELECT 1
|
|
|
|
|
FROM sys.columns c
|
|
|
|
|
WHERE c.object_id = OBJECT_ID(N'dms_report_device_efficiency')
|
|
|
|
|
AND c.name = v.column_name
|
|
|
|
|
)
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- ========== 调用存储过程重算(已废弃)========== -->
|
|
|
|
|
<update id="callSpCalcOee" statementType="CALLABLE">
|
|
|
|
|
{call sp_calc_dms_report_device_efficiency(#{statDate,jdbcType=DATE})}
|
|
|
|
|
</update>
|
|
|
|
|
|
|
|
|
|
<!-- ========================================================================
|
|
|
|
|
OEE 数据采集层 — XML SQL 做擅长的窗口函数/聚合/JOIN
|
|
|
|
|
为什么写在 XML 而非 SP:归一化到应用层管理,部署不限 DBA,可单测
|
|
|
|
|
======================================================================== -->
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
设备五态时长采集(LEAD 窗口函数)
|
|
|
|
|
为什么用 LEAD:每台设备的状态是"快照"模型(sync_time 记录状态变更时刻),
|
|
|
|
|
LEAD 取下一个快照时刻作为当前状态的结束时间,形成时间区间,再与统计日取交集。
|
|
|
|
|
状态映射硬编码原因:dms_status_mapping 字典已定义但 SP 未使用,先保持一致,
|
|
|
|
|
后续统一字典化时一并修改。
|
|
|
|
|
-->
|
|
|
|
|
<select id="selectStateHours" resultType="java.util.LinkedHashMap">
|
|
|
|
|
WITH hist AS (
|
|
|
|
|
SELECT
|
|
|
|
|
h.machine_id,
|
|
|
|
|
h.status_code,
|
|
|
|
|
h.status_name,
|
|
|
|
|
h.status_value,
|
|
|
|
|
h.sync_time,
|
|
|
|
|
LEAD(h.sync_time) OVER (PARTITION BY h.machine_id ORDER BY h.sync_time) AS next_sync_time
|
|
|
|
|
FROM dms_realtime_status_history h
|
|
|
|
|
WHERE h.tenant_id = #{tenantId}
|
|
|
|
|
), state_raw AS (
|
|
|
|
|
SELECT
|
|
|
|
|
h.machine_id,
|
|
|
|
|
m.workshop_id,
|
|
|
|
|
CASE
|
|
|
|
|
WHEN UPPER(h.status_code) IN ('RUN','RUNNING')
|
|
|
|
|
OR h.status_name LIKE '%' + N'运行' + '%'
|
|
|
|
|
OR UPPER(COALESCE(h.status_value,'')) IN ('1','RUN','RUNNING') THEN '0'
|
|
|
|
|
WHEN UPPER(h.status_code) IN ('IDLE','STANDBY')
|
|
|
|
|
OR h.status_name LIKE '%' + N'待机' + '%' THEN '1'
|
|
|
|
|
WHEN UPPER(h.status_code) IN ('FAULT','ALARM')
|
|
|
|
|
OR h.status_name LIKE '%' + N'故障' + '%' THEN '2'
|
|
|
|
|
WHEN UPPER(h.status_code) IN ('STOP','OFF','SHUTDOWN')
|
|
|
|
|
OR h.status_name LIKE '%' + N'停机' + '%' THEN '3'
|
|
|
|
|
WHEN UPPER(h.status_code) IN ('DEBUG','SETUP')
|
|
|
|
|
OR h.status_name LIKE '%' + N'调试' + '%' THEN '4'
|
|
|
|
|
ELSE NULL
|
|
|
|
|
END AS state_type,
|
|
|
|
|
CASE WHEN COALESCE(h.next_sync_time, DATEADD(DAY, 1, #{start})) > h.sync_time THEN
|
|
|
|
|
DATEDIFF_BIG(SECOND,
|
|
|
|
|
CASE WHEN h.sync_time < #{start} THEN #{start} ELSE h.sync_time END,
|
|
|
|
|
CASE WHEN COALESCE(h.next_sync_time, DATEADD(DAY, 1, #{start})) > DATEADD(DAY, 1, #{start})
|
|
|
|
|
THEN DATEADD(DAY, 1, #{start})
|
|
|
|
|
ELSE COALESCE(h.next_sync_time, DATEADD(DAY, 1, #{start})) END)
|
|
|
|
|
ELSE 0 END AS overlap_seconds
|
|
|
|
|
FROM hist h
|
|
|
|
|
LEFT JOIN prod_base_machine_info m ON m.machine_id = h.machine_id
|
|
|
|
|
WHERE h.sync_time < DATEADD(DAY, 1, #{start})
|
|
|
|
|
AND COALESCE(h.next_sync_time, DATEADD(DAY, 1, #{start})) > #{start}
|
|
|
|
|
), state_hours AS (
|
|
|
|
|
SELECT
|
|
|
|
|
machine_id,
|
|
|
|
|
MAX(workshop_id) AS workshop_id,
|
|
|
|
|
SUM(CASE WHEN state_type = '0' THEN overlap_seconds ELSE 0 END) / 3600.0 AS run_hours,
|
|
|
|
|
SUM(CASE WHEN state_type = '1' THEN overlap_seconds ELSE 0 END) / 3600.0 AS standby_hours,
|
|
|
|
|
SUM(CASE WHEN state_type = '2' THEN overlap_seconds ELSE 0 END) / 3600.0 AS fault_hours,
|
|
|
|
|
SUM(CASE WHEN state_type = '3' THEN overlap_seconds ELSE 0 END) / 3600.0 AS shutdown_hours,
|
|
|
|
|
SUM(CASE WHEN state_type = '4' THEN overlap_seconds ELSE 0 END) / 3600.0 AS debug_hours
|
|
|
|
|
FROM state_raw
|
|
|
|
|
WHERE overlap_seconds > 0 AND state_type IS NOT NULL
|
|
|
|
|
GROUP BY machine_id
|
|
|
|
|
)
|
|
|
|
|
SELECT
|
|
|
|
|
machine_id,
|
|
|
|
|
workshop_id,
|
|
|
|
|
run_hours,
|
|
|
|
|
standby_hours,
|
|
|
|
|
fault_hours,
|
|
|
|
|
shutdown_hours,
|
|
|
|
|
debug_hours
|
|
|
|
|
FROM state_hours
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
产出扫描台数聚合
|
|
|
|
|
为什么用 create_time 而非专用时间字段:prod_output_scan_info 无独立产出时间列,
|
|
|
|
|
以记录创建时间作为归属日期的依据(与 MES 模块现有口径一致)
|
|
|
|
|
-->
|
|
|
|
|
<select id="selectOutputQty" resultType="java.util.LinkedHashMap">
|
|
|
|
|
SELECT
|
|
|
|
|
p.machine_id,
|
|
|
|
|
COUNT(1) AS output_qty
|
|
|
|
|
FROM prod_output_scan_info p
|
|
|
|
|
WHERE p.tenant_id = #{tenantId}
|
|
|
|
|
AND p.create_time >= #{start}
|
|
|
|
|
AND p.create_time < #{end}
|
|
|
|
|
GROUP BY p.machine_id
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
工序参数聚合:理论节拍 + 标准机时
|
|
|
|
|
为什么用 MIN 聚合:一台设备可能关联多个工序,取最小值作为"瓶颈工序"
|
|
|
|
|
节拍单位为秒/件,标准机时为 production_time(秒)÷ 3600
|
|
|
|
|
-->
|
|
|
|
|
<select id="selectProcessInfo" resultType="java.util.LinkedHashMap">
|
|
|
|
|
SELECT
|
|
|
|
|
mp.machine_id,
|
|
|
|
|
MIN(pi.theoretical_cycle_time) AS ideal_cycle_time_sec,
|
|
|
|
|
CAST(MIN(ISNULL(pi.production_time, 0)) / 3600.0 AS DECIMAL(18,6)) AS process_std_machine_hours
|
|
|
|
|
FROM prod_base_machine_process mp
|
|
|
|
|
INNER JOIN prod_base_process_info pi ON pi.process_id = mp.process_id AND pi.del_flag = '0'
|
|
|
|
|
WHERE mp.tenant_id = #{tenantId}
|
|
|
|
|
GROUP BY mp.machine_id
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
合格品数量 → 机台归属(需分表处理)
|
|
|
|
|
为什么走 planDetailId → plan_detail → plan_info 链路:
|
|
|
|
|
qc_inspection_main 无 machine_id 字段,只能通过生产计划链路反推。
|
|
|
|
|
为什么用 ${tableSuffix} 而非预编译:
|
|
|
|
|
prod_product_plan_detail 和 prod_plan_info 按车间分表(_{workshopId}),
|
|
|
|
|
表名需要运行时动态拼接,Service 层已校验 tableSuffix 为合法数字
|
|
|
|
|
-->
|
|
|
|
|
<select id="selectQualifiedQtyByWorkshop" resultType="java.util.LinkedHashMap">
|
|
|
|
|
SELECT
|
|
|
|
|
pp.release_id AS machine_id,
|
|
|
|
|
SUM(ISNULL(m.qualified_qty, 0)) AS qualified_qty
|
|
|
|
|
FROM qc_inspection_main m
|
|
|
|
|
INNER JOIN prod_product_plan_detail_${tableSuffix} pd
|
|
|
|
|
ON pd.plan_detail_id = m.plan_detail_id
|
|
|
|
|
AND pd.del_flag = '0'
|
|
|
|
|
INNER JOIN prod_plan_info_${tableSuffix} pp
|
|
|
|
|
ON pp.plan_id = pd.plan_id
|
|
|
|
|
AND pp.release_type = '1'
|
|
|
|
|
WHERE m.tenant_id = #{tenantId}
|
|
|
|
|
AND m.inspection_start_time >= #{start}
|
|
|
|
|
AND m.inspection_start_time < #{end}
|
|
|
|
|
AND m.status = '1'
|
|
|
|
|
AND m.del_flag = '0'
|
|
|
|
|
GROUP BY pp.release_id
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 获取所有激活车间,用于 workshop 名称 → ID 解析 -->
|
|
|
|
|
<select id="selectActiveWorkshops" resultType="java.util.LinkedHashMap">
|
|
|
|
|
SELECT
|
|
|
|
|
workshop_id,
|
|
|
|
|
workshop_name
|
|
|
|
|
FROM prod_base_workshop_info
|
|
|
|
|
WHERE del_flag = '0'
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- ========================================================================
|
|
|
|
|
OEE 持久化层 — 批量 DELETE + INSERT
|
|
|
|
|
======================================================================== -->
|
|
|
|
|
|
|
|
|
|
<!-- 删除指定日期的 OEE 报表(幂等前提) -->
|
|
|
|
|
<delete id="deleteOeeReportByDate">
|
|
|
|
|
DELETE FROM dms_report_device_efficiency
|
|
|
|
|
WHERE stat_date = #{statDate}
|
|
|
|
|
AND tenant_id = #{tenantId}
|
|
|
|
|
</delete>
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
批量 INSERT OEE 报表(含 7 个 OEE 扩展列)
|
|
|
|
|
为什么不用 MyBatis-Plus saveBatch:saveBatch 默认逐条 INSERT,数据量大时慢;
|
|
|
|
|
手写批量 VALUES 一次提交,500 条以内性能最优
|
|
|
|
|
-->
|
|
|
|
|
<insert id="insertOeeReport">
|
|
|
|
|
INSERT INTO dms_report_device_efficiency (
|
|
|
|
|
tenant_id, stat_date, workshop_id, class_team_id, shift_id, machine_id,
|
|
|
|
|
workshop_name, class_team_name, shift_name, machine_name,
|
|
|
|
|
output_qty, process_std_machine_hours,
|
|
|
|
|
debug_hours, run_hours, standby_hours, fault_hours, shutdown_hours,
|
|
|
|
|
output_machine_hours, total_hours, uptime_rate, overall_efficiency, runtime_efficiency,
|
|
|
|
|
qualified_qty, ideal_cycle_time_sec,
|
|
|
|
|
availability_rate, performance_rate, quality_rate, oee_rate, teep_rate,
|
|
|
|
|
create_time
|
|
|
|
|
) VALUES
|
|
|
|
|
<foreach collection="list" item="d" separator=",">
|
|
|
|
|
(
|
|
|
|
|
#{tenantId}, #{statDate},
|
|
|
|
|
#{d.workshopId}, #{d.classTeamId}, #{d.shiftId}, #{d.machineId},
|
|
|
|
|
#{d.workshopName}, #{d.classTeamName}, #{d.shiftName}, #{d.machineName},
|
|
|
|
|
#{d.outputQty}, #{d.processStdMachineHours},
|
|
|
|
|
#{d.debugHours}, #{d.runHours}, #{d.standbyHours}, #{d.faultHours}, #{d.shutdownHours},
|
|
|
|
|
#{d.outputMachineHours}, #{d.totalHours}, #{d.uptimeRate}, #{d.overallEfficiency}, #{d.runtimeEfficiency},
|
|
|
|
|
#{d.qualifiedQty}, #{d.idealCycleTimeSec},
|
|
|
|
|
#{d.availabilityRate}, #{d.performanceRate}, #{d.qualityRate}, #{d.oeeRate}, #{d.teepRate},
|
|
|
|
|
GETDATE()
|
|
|
|
|
)
|
|
|
|
|
</foreach>
|
|
|
|
|
</insert>
|
|
|
|
|
|
|
|
|
|
</mapper>
|