2. 批次追溯断链:从成品批号反查原料投料记录

断链定位思路:沿批次关联表逐级反查

成品批号追溯断链,本质是批次关联表(batch_link)中某一级父子关系缺失或指向错误。食品MES中一条完整追溯链通常为:原料批次 → 投料记录 → 称量记录 → 混合记录 → 包装记录 → 成品批次。反查时不要从原料正向猜,而应从成品批号出发,逐级向上游取父批次,每跳一级就核对“关联表有记录、业务表有明细、批次号一致”三件事。

假设成品批号 FG-20240612-003 在MES中反查时,第3级(混合→称量)返回空。下面用一张链路图表示各级节点、关联表跳转与断点位置,便于对照排查。

成品批号 FG-20240612-003 反查链路(自右向左逐级上溯) 成品批次 FG-20240612-003 包装记录 PK-20240612-021 混合记录 MX-20240612-009 称量记录 WL-20240612-014 (关联缺失) 投料记录 RM-20240612-005 父批次 父批次 断链 父批次 batch_link 关联表逐级查询(child_batch → parent_batch) ① FG-20240612-003 → PK-20240612-021 ✓ 存在 ② PK-20240612-021 → MX-20240612-009 ✓ 存在 ③ MX-20240612-009 → WL-20240612-014 ✗ 缺失(断点) ④ WL-20240612-014 → RM-20240612-005 ✓ 存在 称量记录本身存在,但混合记录未写入其父批次关联 → 断链发生在“混合工序写入称量批次关联”环节 断点判定三查 查关联表:batch_link 中 MX-20240612-009 是否有 child 记录指向 WL-20240612-014 查业务表:称量记录 WL-20240612-014 是否存在且状态为“已完成” 查写入日志:混合工序报工/入库时是否触发批次关联写入,是否有异常回滚

反查SQL与断点确认

用递归查询从成品批号向上追溯,能一次性看到链路在哪一级断开。以下SQL以MySQL 8的递归CTE为例,batch_link表字段为 child_batch、parent_batch、process_code、create_time。

WITH RECURSIVE trace AS (
  SELECT child_batch, parent_batch, process_code, 1 AS lvl
  FROM batch_link
  WHERE child_batch = 'FG-20240612-003'
  UNION ALL
  SELECT b.child_batch, b.parent_batch, b.process_code, t.lvl + 1
  FROM batch_link b
  JOIN trace t ON b.child_batch = t.parent_batch
  WHERE t.lvl < 10
)
SELECT lvl, child_batch, parent_batch, process_code
FROM trace
ORDER BY lvl;

若查询结果只到 MX-20240612-009 就停止,说明该混合批次没有父批次记录。此时再单独确认称量记录是否存在:

SELECT batch_no, status, create_time
FROM weigh_record
WHERE batch_no = 'WL-20240612-014';

若称量记录存在且状态正常,则断链原因在混合工序写入关联时未成功,而非称量数据缺失。常见原因包括:混合报工时事务回滚、批次关联写入接口超时、称量批次号在混合工序被错误替换。

修复与链路完整性验证

确认断点后,补写缺失的关联记录,并验证整条链路可完整反查。补写前先核对混合记录与称量记录的实际对应关系,避免补错父批次。

-- 补写缺失关联(示例,需先确认对应关系)
INSERT INTO batch_link (child_batch, parent_batch, process_code, create_time)
VALUES ('MX-20240612-009', 'WL-20240612-014', 'MIXING', NOW());

-- 验证:从成品批号反查应能到达原料批次
WITH RECURSIVE trace AS (
  SELECT child_batch, parent_batch, process_code, 1 AS lvl
  FROM batch_link WHERE child_batch = 'FG-20240612-003'
  UNION ALL
  SELECT b.child_batch, b.parent_batch, b.process_code, t.lvl + 1
  FROM batch_link b JOIN trace t ON b.child_batch = t.parent_batch
  WHERE t.lvl < 10
)
SELECT COUNT(*) AS chain_depth,
       MAX(CASE WHEN parent_batch LIKE 'RM-%' THEN 1 ELSE 0 END) AS reach_raw
FROM trace;

验证通过条件:chain_depth 达到预期级数(本例为5级),且 reach_raw = 1,表示链路已能追溯到原料批次。修复后还应检查同一混合工序的其他批次是否存在相同断链,避免只补单点。

反查时优先用递归SQL一次性拉出整条链路,比逐级手工查表更快定位断点;补写关联记录前必须核对业务表实际对应关系,不能凭批号规则猜测父批次。