# 两天台账排查逻辑与案例总结 ## 1. 这次排查覆盖了哪些对象 这两天实际排查的对象,分成 5 类: 1. 半成品收发存原表 `YDM_BC_INITIAL / YDM_BC_INLIST / YDM_BC_OUTLIST` 2. 半成品中间表 `CX_YDM_BC_INITIAL / CX_YDM_BC_INLIST / CX_YDM_BC_OUTLIST` 3. 成品收发存原表 `YDM_ZC_INITIAL / YDM_ZC_INLIST / YDM_ZC_OUTLIST / YDM_ZC_STOCKTAKINGLIST` 4. 成品中间表 `CX_YDM_ZC_INITIAL / CX_YDM_ZC_INLIST / CX_YDM_ZC_OUTLIST` 5. 月报与接口 - 热轧月报:`HOT_PRODUCTION_MES_RZ` - 加工月报:`HOT_PRODUCTION_MES_JG` - 判定表:`QCM_ZG_JUGDE_APPLY` - 接口日志:`CX_TO_MES_LOG` - 提单表:`YDM_ZC_BILL_M / YDM_ZC_BILL_C / YDM_ZC_LOADVEHICLE_MAT` 这 5 类对象里,最容易混淆的是: - 原表 `YDM_*`:更像“当前业务真实源头” - 中间表 `CX_*`:更像“给校验/接口/月报使用的结果表” - `DataValidationResult`:只是某一时点的校验快照,不代表当前库里实时值 所以排查时第一原则是: **永远先分清“是原表错了,还是 CX 表错了,还是校验结果只是旧快照”。** ## 2. 核对的基本公式 ### 2.1 半成品/成品跨月连续性 最常用的判断公式是: `本月期初 = 上月期初 + 上月入库 - 上月出库 (+ 调差)` 其中: - 半成品常用: - 期初:`YDM_BC_INITIAL` - 入库:`YDM_BC_INLIST` - 出库:`YDM_BC_OUTLIST` - 成品常用: - 期初:`YDM_ZC_INITIAL` - 入库:`YDM_ZC_INLIST` - 出库:`YDM_ZC_OUTLIST` - 调差:`YDM_ZC_STOCKTAKINGLIST` ### 2.2 月报和台账对比 月报不是直接跟“成品量”比,而是要先明确过程口径。 这次已经确认过一类典型问题: - 有些第三方是直接拿 `PROD_WEIGHT` - 但系统过程实际用的是 `PROD_WEIGHT - NVL(LC_WEIGHT, 0)` 所以月报类问题第二原则是: **先确认“月报值的生成公式”,再谈是不是对不上。** ## 3. 标准排查流程 后面再遇到类似问题,建议固定按下面 8 步走。 ### 第 1 步:先确认问题是“哪一层”报出来的 先看报错来自哪里: - `DataValidationResult` - 第三方接口校验 - 人工 Excel 对账 - 月报和台账比对 这一步的目的,是避免把“汇总口径问题”误当成“明细错误”。 ### 第 2 步:先做月度总额复核 先按物料或全口径聚合,确认差多少。 例如: - `202601 -> 202602` 成品只差 `0.020t` - `202603 -> 202604` 成品差 `2支 / 3.969t` 这一步只回答一个问题: **到底是“大面积错”,还是“少数几条炉号造成的总差”。** ### 第 3 步:再下钻到炉号 总额确认后,一定要立刻切到炉号级。 因为物料级报错里,常见会混进: - 改判 - 换物料编码 - 红冲 - 月末 0 支尾重 - 同炉号跨工序迁移 这些问题在物料级看起来像“差了很多”,但炉号级一拆就能分出: - 真错 - 改判 - 历史残留 ### 第 4 步:同一炉号同时看原表和 CX 表 每个异常炉号至少要看 2 套数据: 1. 原表 `YDM_*` 2. 中间表 `CX_*` 这一步的目的是把问题分型成: - 原表错,CX 只是抄过去 - 原表已经对了,但 CX 还是旧值 - 原表没有,CX 多了 - 原表有,CX 漏了 ### 第 5 步:看是不是“改判/换物料编码” 这一类在这次排查里占比很高。 表现形式通常是: - 同一个炉号 - 上月在物料 A - 下月或同月出库在物料 B 如果炉号本身是平的,只是物料变了,那通常不应该按“库存错误”处理,而应该按: **改判说明** ### 第 6 步:看是不是“重复插入” 这次也遇到过非常典型的重复灌数: - 原表应有 1 条 - `CX` 里被插了 4 次 这种问题最明显的特征是: - 原表和业务逻辑都解释不出来这么大的数 - 同一炉号、同一月份、同一数量重量,`CX` 里出现多条 ### 第 7 步:确定该改哪一层 这个很重要。 不是所有问题都该改原表。 判断规则: - 原表正确,CX 错:改 `CX` - 原表月份挂错:改原表,必要时同步 `CX` - 属于改判:不改库存,出说明 - 属于月报算法问题:改过程逻辑或月报结果,不改收发存 ### 第 8 步:修完以后一定复核 修完至少做 3 次复核: 1. 行级是否对平 2. 物料汇总是否对平 3. 相关校验过程重跑后是否符合预期 ## 4. 这次遇到的典型错误类型与案例 下面把这两天碰到的典型问题,按类型整理。 --- ## 4.1 期初带错 ### 典型案例:半成品 202601 -> 202602 涉及炉号: - `A26010132` - `A26010135` - `A26010139` - `C26010317` 问题表现: - `2026-01` 期末和 `2026-02` 期初对不上 - 这 4 个炉号在 `202602` 的 `YDM_BC_INITIAL` 被写成了“上月入库量” - 不是“上月期末量” 例如: `A26010132` - 1 月实际期末:`1支 / 1.48吨` - 2 月期初却写成:`64支 / 97.188吨` 最终处理: - 修 `202602` 的 `YDM_BC_INITIAL` - 再核 `202601 -> 202602 -> 202603 -> 202604` 经验结论: **如果某月期初恰好等于上月某类入库,而不是上月期末,优先怀疑期初生成逻辑错把“入库承接”当成“结存承接”。** ## 4.2 原表已改正,CX 还停留在旧值 ### 典型案例:`TQ9618310507410B` 涉及炉号: - `A26010109` - `A26010113` - `A26010120` - `A26010132` - `A26010135` - `A26010139` - `C26010317` 问题表现: - 当前原表已经改正 - 但 `CX_YDM_BC_*` 里还是旧数据 - 导致 `check_material_balance` 或 `DataValidationResult` 继续报错 处理方式: - 不回头再改原表 - 直接把 `CX` 按当前原表同步 经验结论: **先看“现在的原表”是不是已经对了,再决定要不要动源表。很多时候问题只是结果表没刷新。** ## 4.3 重复插入 ### 典型案例:`TQ0218312001410B` 涉及炉号: - `A25070249` - `A25070271` - `A25080210` 原表应有: - `A25070249`:`1支 / 1.305吨` - `A25070271`:`1支 / 1.646吨` - `A25080210`:`2支 / 3.213吨` `CX_YDM_BC_OUTLIST` 实际却是每条 4 次: - `A25070249`:`4行 / 4支 / 5.220吨` - `A25070271`:`4行 / 4支 / 6.584吨` - `A25080210`:`4行 / 8支 / 12.852吨` 处理方式: - 保留最早 1 条 - 删除后面 3 条重复数据 经验结论: **同一炉号、同一月份、同一数量重量重复出现时,不要先怀疑业务,先怀疑 `CX` 持久化被重复执行。** ## 4.4 改判/换物料编码 ### 典型案例 1:`TQ9618310507410B` 与 `TQ9618312007410B` 表现: - 同一批炉号 - `2026-02` 在 `TQ9618312007410B` - `2026-03` 期初挂到了 `TQ9618310507410B` 这类问题在物料级会表现为: - 一个物料突然多 - 另一个物料突然少 但炉号级看是平的,只是物料变了。 这种情况更适合: - 出“改判说明” - 不按普通库存错账处理 ### 典型案例 2:`TD0719312307411B` 涉及炉号: - `C26010494` 历史 `CX` 快照里: - `TD0719312307411B` 表面剩 `5支 / 12.618吨` - 同炉号又有 `TQ5612412301411B` 出库 `5支 / 12.618吨` 这就是典型“同炉号跨物料改判”。 经验结论: **只要同一炉号跨物料迁移且炉号级自平,优先归类为改判,不要急着补期初。** ## 4.5 尾重 ### 典型案例 1:成品 `A22070051` 问题: - `202601` 期末到 `202602` 期初只差 `0.020吨` 最后处理: - 在 `YDM_ZC_STOCKTAKINGLIST` 补了一条 `202601` 调差 - 重量 `-0.02` - 后来又把规格调整成正确的 `533.8x24.5` ### 典型案例 2:`TB8818212001411C` 涉及炉号: - `A25050280` 原始情况: - 期初:`1支 / 2.258吨` - 负入库:`-1支 / -2.095吨` - 导致期末形成 `0支 / 0.163吨` 尾重 处理方式: - 把负入库重量改成和期初一致 - `-2.095 -> -2.258` 经验结论: **只差零点几吨、支数为 0 的,优先按尾重处理。** ## 4.6 红冲导致跨月不平 ### 典型案例:成品 `A25100221`、`A25100033` 表现: - `202603` 没有期初、没有入库 - 但出现了 `800806` 负出库红冲 例如: `A25100221` - `2026-03` 出现 `800806 = -1支 / -2.265吨` - 会把库存冲回成 `1支 / 2.265吨` - 但 `202604` 期初没承接 `A25100033` - `202602` 本来已清零 - `202603` 又有 `800806 = -1支 / -1.704吨` - 又被冲回 `1支 / 1.704吨` - `202604` 也没承接 经验结论: **没有期初、没有入库,不代表不可能有库存。只要有负出库红冲,就可能把历史库存冲回来。** ## 4.7 月份挂错 ### 典型案例:`TQ4577615272411B / C26030094` 问题: - 月报里 `2026-03` 该有 `24支 / 23.233吨` - `CX_YDM_BC_INLIST` 里只有 `12支 / 11.393吨` 后来追到原表发现: - 另一半 `12条 / 11.84吨` 被挂在了 `202604` - 实际应属于 `202603` 处理方式: - 把原表 `YDM_BC_INLIST` 那 `12` 条的 `BAL_YEAR_MONTH` - `202604 -> 202603` - 再同步 `CX` 处理后: - 月报 `72.867` - 台账 `72.867` - 对平 经验结论: **如果差值能完整在相邻月份找到,优先怀疑 `BAL_YEAR_MONTH` 挂错,而不是重量算错。** ## 4.8 月报来料重量算法错误 ### 典型案例:加工月报 `TQ9618310507203B` 问题表: - `HOT_PRODUCTION_MES_JG` - 来源过程:`MES_CX_JG_ZXNEW_HAND` 异常表现: - `mate_weight` 只有 `2~3吨` - `prod_weight` 却有 `90~125吨` - `steel_waste` 被算成 `3900%` 根因: - 过程用的是 `mate_weight = sum(qcm.input_weight) + 接箍重量` - 但这批 `G` 工序记录里,`QCM_ZG_JUGDE_APPLY.INPUT_WEIGHT` 大量为 0 - 结果只剩接箍重量 后来按你的业务逻辑核定: **前一道工序的成品量 = 下一道工序的投料量** 示例: `A24120546` `D` 工序合计: - `ACT_COUNT = 76` - `ACT_WEIGHT = 94.992` `G` 工序当前: - `ACT_COUNT = 76` - `ACT_WEIGHT = 99.307` - `INPUT_WEIGHT = 0` 所以应补: - `G.INPUT_WEIGHT = 94.992` 对应月报重算: - 原 `MATE_WEIGHT = 2.509` - 改后 `MATE_WEIGHT = 94.992 + 2.509 = 97.501` - 原 `STEEL_WASTE = 3958.0311` - 改后 `STEEL_WASTE = 101.8523` 最后处理: - 改了 `QCM_ZG_JUGDE_APPLY` - 同时改了 `HOT_PRODUCTION_MES_JG` - 并做了可回滚备份 经验结论: **月报“来料重量很离谱”时,不要直接改结果表,先追来源公式。** ## 4.9 接口重复接收与提单异常 ### 典型案例:`KHFT260325016` 日志顺序: 1. `GetYdmZcBillDate` 2. `BillRevoke` 3. `GetYdmZcBillDate` 另外核到: - 两次 `GetYdmZcBillDate` 的 `SOCKET_PARMER` - 除 `planStartTime / planEndTime` 外,其余完全一致 - 也就是同一张提单被重复推送了一次 同时还发现: - 提单主表曾出现过两条 - 明细只有 25 条,不是重复 50 条 - `BillClose` 传参里的炉号和库里的 `JUDGE_STOVE_NO` 对不上 - `YDM_ZC_BILL_C.LOADVEHICLE_FLAG` 还有 14 支没同步成已装车 经验结论: **接口问题一定要同时看:接口日志、主表、明细表、装车表、代码匹配字段。只看一张表很容易误判。** ## 5. 如何判断“该补数据”还是“该出说明” 后面再碰到问题,可以直接按下面判断。 ### 应该补数据 满足以下任一: - 原表月份挂错 - `CX` 重复插入 - `CX` 漏同步 - 尾重非常明确,且能精确落到一条记录 - 红冲/调差值能明确定位到某行 ### 不建议直接补数据 满足以下任一: - 同炉号跨物料改判 - 月报来源逻辑本身不对 - 当前原表已经查不到来源,只剩历史快照 - 只能看出总差,无法落到具体炉号和具体行 ### 应该出说明 满足以下任一: - 炉号级平衡,只是物料编码变了 - 外部按物料汇总报错,但内部按炉号级不算错 - 第三方校验口径和系统口径不一致 ## 6. 一个实战排查模板 后面你自己核某个问题,可以直接照这个顺序: 1. 先写下问题对象 物料、合同、月份、报错内容 2. 先做月度总额对账 `期初 + 入库 - 出库 (+ 调差) = 期末` 3. 再拆到炉号 找出差异是哪些炉号造成的 4. 同时查原表和 `CX` 5. 判断是以下哪类: - 期初带错 - 原表已改,`CX` 未同步 - 重复插入 - 改判 - 尾重 - 红冲 - 月份挂错 - 月报算法问题 - 接口重复或字段错配 6. 决定处理方式: - 改原表 - 改 `CX` - 改月报来源表 - 仅出说明 7. 修完后复核: - 行级 - 炉号级 - 物料级 - 校验结果 ## 7. 可直接复用的 SQL 思路 下面不是最终 SQL,只是核对时最常用的模式。 ### 7.1 查某物料某月原表入出 ```sql select * from ydm_bc_inlist t where t.bal_year_month = '202603' and t.material_no = '物料编码'; ``` ```sql select * from ydm_bc_outlist t where t.bal_year_month = '202603' and t.material_no = '物料编码'; ``` ### 7.2 查某炉号 1-4 月全链路 ```sql select 'INITIAL' src, t.bal_year_month, t.material_no, t.judge_stove_no, t.act_count, t.act_weight from ydm_bc_initial t where t.judge_stove_no = '炉号' union all select 'INLIST', t.bal_year_month, t.material_no, t.judge_stove_no, t.act_count, t.act_weight from ydm_bc_inlist t where t.judge_stove_no = '炉号' union all select 'OUTLIST', t.bal_year_month, t.material_no, t.judge_stove_no, t.act_count, t.act_weight from ydm_bc_outlist t where t.judge_stove_no = '炉号'; ``` ### 7.3 查原表和 CX 是否一致 做法不是只比汇总,而是至少比: - 月份 - 物料 - 炉号 - 合同 - 支数 - 重量 如果汇总一样但明细不一样,后面还是会炸。 ## 8. 这次已经被验证过的经验 最后把这两天最有用的结论压成几句话,后面很好用。 1. 先看炉号,再看物料。 很多“物料不连续”,其实是炉号改判。 2. 先看原表,再看 `CX`。 很多问题只是结果表旧了,不是源头错了。 3. 尾差优先看调差和红冲。 尤其是 `0支 非0吨`,十有八九不是正常库存。 4. 月报不要直接拿结果说话。 先搞清楚是从哪张判定表、按什么公式写出来的。 5. 接口问题一定要串日志、代码、数据库。 只看其中一块,很容易得出错结论。 ## 9. 当前还值得继续追的点 截至当前,这几类仍然属于“后续可以继续排查”的方向: - 当前库里完全没有、但外部说有的数据 例如某些销售结算接口物料 - 月报有值、原表当前查不到来源的数据 例如曾遇到的 `TQ5612510601412B` - 改判链跨了多个月、当前只剩历史快照的数据 这类问题的共同点是: **不能只靠当前原表,还要追历史快照、过程、接口源表。** ## 10. 一句话版总结 这两天所有问题,归根到底都是下面几类: - 承接错 - 月份挂错 - `CX` 没同步 - `CX` 重复插入 - 红冲/尾重 - 改判 - 月报公式取错来源 - 接口重复推送或匹配字段不一致 只要后面排查时固定坚持: **先总额、再炉号、再原表/CX 对照、最后再决定改数据还是出说明** 大多数问题都能很快定位清楚。