# 月结逻辑交接说明

## 1. 文档目的
本文用于交接 MES 月结执行逻辑，重点说明以下内容：

- 月结前需要先处理什么前置条件
- 月结时哪些结果表需要先观察、再删除、再重建
- 各阶段存储过程分别负责什么
- 每个存储过程主要查询哪些原表
- 每个存储过程有哪些核心过滤条件
- 每个存储过程最终写入到哪张结果表
- 月报与收发存对比时需要注意哪些业务口径
- 月结完成后如何校验，以及异常时怎么排查

本文以 `2026-03` 月结为例说明。后续换月份时，只需要把“当前月 / 次月”替换为对应月份即可。

## 2. 核心原则

1. 月结重建的是结果表，不是来源表。来源表、判定表是输入，`CX_*` 和 `HOT_*` 是结果。
2. 月结必须先清旧结果，再跑过程；不要在已有结果上重复叠加。
3. 正式月结前，必须先确认相关定时 job 已停掉、禁用或删除，否则删表后结果会被后台任务重新写回。
4. 正式月结前，必须检查存储过程中是否残留“临时补数据用的炉号条件”；如果有，正式月结时应注释掉或忽略。
5. 存储过程内部本身带事务和 `commit`，正常执行时直接调用即可。
6. 月结后统一执行校验过程，再看 `DataValidationResult`，不要用历史校验快照判断当前数据。

## 3. 数据分层

### 3.1 来源层
这层是过程直接取数的原始或判定数据，主要包括：

- 半成品来源表：`YDM_BC_INITIAL`、`YDM_BC_INLIST`、`YDM_BC_OUTLIST`
- 成品来源表：`YDM_ZC_INITIAL`、`YDM_ZC_INLIST`、`YDM_ZC_OUTLIST`、`YDM_ZC_STOCKTAKINGLIST`
- 判定表：`QCM_ZG_JUGDE_APPLY`
- 工艺和在产品相关表：例如加工、热处理、热轧、装车、取样、计划等表
- 物料映射表：`MVM_ORDER_MATNO_INFO`
- 订单映射视图：`ORDERDETAIL_V@TH_CX_LINK`

来源层的典型特点：

- 月份字段大多使用 `YYYYMM`，例如 `202603`
- 原表中的物料编码不一定是最终进入 `CX` 结果表的物料编码
- 很多过程是先按炉号反查合同，再按合同去映射表找最终物料编码

### 3.2 收发存结果层
这层是月结重建出来的收发存台账结果表：

- 半成品：
  - `CX_YDM_BC_INITIAL`
  - `CX_YDM_BC_INLIST`
  - `CX_YDM_BC_OUTLIST`
- 成品：
  - `CX_YDM_ZC_INITIAL`
  - `CX_YDM_ZC_INLIST`
  - `CX_YDM_ZC_OUTLIST`

这层的典型特点：

- 月份字段通常是 `YYYY-MM`，例如 `2026-03`
- 是后续校验、对账、接口取数的主要结果层
- 如果同月重复执行过程而没有先删旧结果，最容易出现重复数据

### 3.3 月报结果层
这层是生产月报和在产品相关结果表：

- `HOT_PRODUCTION_MES_JG`
- `HOT_HEAT_PRODUCTION_MES_GX`
- `HOT_PRODUCTION_MES_RZ`

这层典型特点：

- 结果是通过判定表、工艺过程表、库存表等重新汇总生成
- 月份字段通常是 `YYYY-MM`
- 生产月报不等于收发存原表简单求和，必须按过程定义的逻辑理解

### 3.4 校验结果层

- `DataValidationResult`

这张表只保存校验结果，不是业务来源。  
每次重跑 `usp_ValidateProductionData` 后，都要以最新一轮结果为准。

## 4. 月份口径

### 4.1 月份格式
系统中常见两种月份格式：

- 来源表、判定表常用：`YYYYMM`
  - 例如 `202603`
- 结果表、月报表、校验过程常用：`YYYY-MM`
  - 例如 `2026-03`

### 4.2 2026-03 月结时的口径
如果本次跑的是 `2026-03` 月结，则：

- 当前月来源口径：`202603`
- 当前月结果口径：`2026-03`
- 次月来源口径：`202604`
- 次月结果口径：`2026-04`

### 4.3 在产品过程的特殊性
在产品类过程不是只看单月，而是通常同时涉及：

- 当前月
- 次月

所以对于 `2026-03` 月结：

- 当前月用 `202603 / 2026-03`
- 次月用 `202604 / 2026-04`

不要把在产品过程里的次月逻辑简单删掉，也不要把所有硬编码月份都机械改成同一个值。

## 5. 正式月结前的前置检查

### 5.1 先处理定时 job
正式删表和跑过程之前，必须先确认相关定时 job 已经停掉、禁用或删除。

原因：

- 月结删除的是结果表，不是来源表
- 如果 job 仍在运行，删表后它可能会立刻重新写入结果表
- 这样会导致手工月结和后台任务并发写数，出现重复、错月或半重建状态

建议执行顺序：

1. 停掉、禁用或按现场要求删除相关 job
2. 确认结果表不会再被后台自动写入
3. 再执行删表
4. 删表后手工按阶段跑月结过程

### 5.2 检查是否有临时炉号条件
正式月结前，要重点检查存储过程中是否残留以下类型的临时条件：

- `judge_stove_no = ...`
- `judge_stove_no in (...)`
- 其他只针对少量炉号的临时补数过滤条件

这类条件通常是在补数据时临时加的，正式月结时应注释掉或忽略。  
本次 2026-03 已经处理过一处明确问题：

- `mes_cx_ydm_zc_inlist_new_hand`
  - 已将过程中的月份改为 `202603`
  - 已将临时炉号过滤注释掉

### 5.3 检查硬编码月份
月结前必须逐个确认相关过程中的硬编码月份是否已经切换到当前月。  
对于 2026-03，来源表条件通常应为 `202603`，结果表或月报过程通常应为 `2026-03`。

## 6. 建议的执行顺序

1. 停 job
2. 检查过程里的月份和临时过滤条件
3. 观察旧结果表数据
4. 删除旧结果表数据
5. 执行阶段 1：半成品台账
6. 执行阶段 2：成品台账
7. 执行阶段 3：生产月报
8. 执行阶段 4：在产品及结构性结果
9. 执行统一校验
10. 查看校验结果
11. 如有异常，再按“来源表 -> `CX_*` -> `HOT_*` -> 校验结果”的顺序排查

## 7. 结果表观察与删除

### 7.1 生产月报结果
```sql
-- 加工生产月报
select sum(t.prod_weight), sum(t.lc_weight)
  from hot_production_mes_jg t
 where t.acct_period = '2026-03'
   and t.prod_type in ('在产品');

delete hot_production_mes_jg t
 where t.acct_period = '2026-03';

-- 热处理生产月报
select count(1)
  from HOT_HEAT_PRODUCTION_MES_GX t
 where t.acct_period = '2026-03'
   and t.prod_type in ('在产品');

delete HOT_HEAT_PRODUCTION_MES_GX t
 where t.acct_period = '2026-03';

-- 热轧生产月报
select *
  from HOT_PRODUCTION_MES_RZ t
 where t.acct_period = '2026-03'
   and t.prod_type in ('在产品');

delete HOT_PRODUCTION_MES_RZ t
 where t.acct_period = '2026-03'
   and t.prod_type in ('在产品');
```

### 7.2 半成品收发存结果
```sql
-- 半成品期初
select count(1)
  from CX_YDM_BC_INITIAL t
 where t.bal_year_month = '2026-03';

delete CX_YDM_BC_INITIAL t
 where t.bal_year_month = '2026-03';

-- 半成品入库
select count(1), sum(t.act_in_weight), sum(t.act_in_count)
  from CX_YDM_BC_INLIST t
 where t.bal_year_month = '2026-03';

delete CX_YDM_BC_INLIST t
 where t.bal_year_month = '2026-03';

-- 半成品出库
select count(1), sum(t.act_out_weight), sum(t.act_out_count)
  from CX_YDM_BC_OUTLIST t
 where t.bal_year_month = '2026-03';

delete CX_YDM_BC_OUTLIST t
 where t.bal_year_month = '2026-03';
```

### 7.3 成品收发存结果
```sql
-- 成品期初
select count(1)
  from CX_YDM_ZC_INITIAL t
 where t.bal_year_month = '2026-03';

delete CX_YDM_ZC_INITIAL t
 where t.bal_year_month = '2026-03';

-- 成品入库
select count(1), sum(t.act_in_weight), sum(t.act_in_count)
  from CX_YDM_ZC_INLIST t
 where t.bal_year_month = '2026-03';

delete CX_YDM_ZC_INLIST t
 where t.bal_year_month = '2026-03';

-- 成品出库
select count(1), sum(t.act_out_weight), sum(t.act_out_count), sum(t.differential)
  from CX_YDM_ZC_OUTLIST t
 where t.bal_year_month = '2026-03';

delete CX_YDM_ZC_OUTLIST t
 where t.bal_year_month = '2026-03';
```

## 8. 阶段 1：半成品收发存

### 8.1 `MES_CX_YDM_BC_INITIAL_hand`
作用：

- 持久化半成品期初结果到 `CX_YDM_BC_INITIAL`

主要来源表：

- `YDM_BC_INITIAL`
- `MVM_ORDER_MATNO_INFO`

主要查询逻辑：

- 先从 `YDM_BC_INITIAL` 取当前月半成品期初
- 通过合同号或 `get_cp_order(judge_stove_no)` 反查合同
- 再去 `MVM_ORDER_MATNO_INFO` 映射最终物料编码和物料名称

核心条件：

- `t1.bal_year_month in ('202603')`
- `t1.belong_code = '002023005'`
- 合同不在一批排除名单内
- 合同不以 `ZZBY%` 开头

写入目标：

- `insert into CX_YDM_BC_INITIAL`

结果特点：

- 月份会转换成 `2026-03` 这种格式
- `bc_type` 写成半成品期初类型
- 结果层已经是最终用于对账和校验的半成品期初

### 8.2 `mes_cx_ydm_bc_inlist_csjg_hand`
作用：

- 处理车丝加工相关的半成品入库结果，写入 `CX_YDM_BC_INLIST`

主要来源表：

- `YDM_ZC_INLIST`
- `ORDERDETAIL_V@TH_CX_LINK`

主要查询逻辑：

- 以车丝加工相关来源表记录为基础
- 结合订单视图做物料和订单关联
- 汇总后写入半成品入库结果表

核心条件：

- `instock_type_code in ('800701', '800702', '800706')`
- `bal_year_month = '202603'`
- `belong_code in ('100101', '100102', '100105')`
- `supply_unit_code = '120504'`
- 合同不以 `ZZBY%` 开头
- `PLINE_CODE = 'C108'`

写入目标：

- `insert into CX_YDM_BC_INLIST`

说明：

- 名称中的 `CSJG` 应理解为车丝加工相关过程

### 8.3 `mes_cx_ydm_bc_inlist_new_hand`
作用：

- 持久化半成品入库结果到 `CX_YDM_BC_INLIST`

主要来源表：

- `YDM_BC_INLIST`
- `MVM_ORDER_MATNO_INFO`

主要查询逻辑：

- 从 `YDM_BC_INLIST` 取当前月半成品入库数据
- 按炉号反查合同
- 再用合同去 `MVM_ORDER_MATNO_INFO` 映射物料编码

核心条件：

- `t1.bal_year_month in ('202603')`
- `t1.belong_code = '002023005'`
- `instock_type_code in ('800704', '800706', '800709')`
- 合同不以 `ZZBY%` 开头

写入目标：

- `insert into CX_YDM_BC_INLIST`

月结注意：

- 正式月结前，如果过程里有临时炉号过滤，应注释掉
- 名称中的 `_NEW_HAND` 不作为业务口径判断依据，实际以 SQL 取数条件为准

### 8.4 `mes_cx_ydm_bc_outlist_csjg`
作用：

- 处理车丝加工相关的半成品出库结果，写入 `CX_YDM_BC_OUTLIST`

主要来源表：

- `YDM_ZC_INLIST`
- `ORDERDETAIL_V@TH_CX_LINK`

主要查询逻辑：

- 以车丝加工相关记录为来源
- 结合订单视图获取最终物料归属
- 汇总生成半成品出库结果

核心条件：

- `instock_type_code in ('800701', '800702', '800706')`
- `bal_year_month in ('202603')`
- `belong_code in ('100101', '100102', '100105')`
- `supply_unit_code = '120504'`
- 合同不以 `ZZBY%` 开头
- `PLINE_CODE = 'C108'`

写入目标：

- `insert into CX_YDM_BC_OUTLIST`

### 8.5 `mes_cx_ydm_bc_outlist_new_hand`
作用：

- 持久化半成品出库结果到 `CX_YDM_BC_OUTLIST`

主要来源表：

- `YDM_BC_OUTLIST`
- `MVM_ORDER_MATNO_INFO`

主要查询逻辑：

- 从 `YDM_BC_OUTLIST` 取当前月出库数据
- 按炉号反查合同
- 用合同映射最终物料编码

核心条件：

- `t1.bal_year_month in ('202603')`
- `t1.belong_code = '002023005'`
- `outstock_type_code in ('800809', '800808', '800806')`
- 合同不以 `ZZBY%` 开头

写入目标：

- `insert into CX_YDM_BC_OUTLIST`

## 9. 阶段 2：成品收发存

### 9.1 `mes_cx_ydm_zc_initialnew_hand`
作用：

- 持久化成品期初到 `CX_YDM_ZC_INITIAL`

主要来源表：

- `YDM_ZC_INITIAL`
- `MVM_ORDER_MATNO_INFO`

主要查询逻辑：

- 从成品期初原表取当前月数据
- 按合同号映射最终物料编码
- 形成成品期初结果

核心条件：

- `t1.handle_log = '1'`
- `t1.bal_year_month in ('202603')`
- `belong_code in ('100101', '100102', '100105')`
- `supply_unit_code = '120504'`
- 合同不以 `ZZBY%` 开头

写入目标：

- `insert into CX_YDM_ZC_INITIAL`

### 9.2 `mes_cx_ydm_zc_inlist_new_hand`
作用：

- 持久化成品入库到 `CX_YDM_ZC_INLIST`

主要来源表：

- `YDM_ZC_INLIST`
- `MVM_ORDER_MATNO_INFO`

主要查询逻辑：

- 从成品入库原表取当前月入库
- 按 `pro_order_no` 或 `get_cp_order(judge_stove_no)` 反查合同
- 用 `MVM_ORDER_MATNO_INFO` 映射最终成品物料编码
- 再写入 `CX_YDM_ZC_INLIST`

核心条件：

- `instock_type_code in ('800701', '800702', '800706', '800704')`
- `belong_code in ('100101', '100102', '100105')`
- `supply_unit_code = '120504'`
- 合同不以 `ZZBY%` 开头
- 当前 2026-03 月结时，过程内月份应为 `202603`

写入目标：

- `insert into CX_YDM_ZC_INLIST`

月结注意：

- 这是本次已经明确修正过的过程之一
- 正式月结前必须再次确认过程内月份仍是 `202603`
- 正式月结时不允许保留临时炉号过滤条件

### 9.3 `mes_cx_ydm_zc_outlist_new_hand`
作用：

- 持久化成品出库到 `CX_YDM_ZC_OUTLIST`

主要来源表：

- `YDM_ZC_STOCKTAKINGLIST`
- `YDM_ZC_OUTLIST`
- `YDM_ZC_INITIAL`
- `YDM_ZC_INLIST`
- `MVM_ORDER_MATNO_INFO`

主要查询逻辑：

- 组合成品出库、调差、期初、入库等来源
- 统一映射物料编码
- 汇总后写入成品出库结果表

核心条件：

- 当前月口径为 `202603`
- 具体业务类型由过程内部 SQL 控制

写入目标：

- `insert into CX_YDM_ZC_OUTLIST`

## 10. 阶段 3：生产月报

### 10.1 `mes_cx_jg_zxnew_hand`
作用：

- 生成加工生产月报，写入 `HOT_PRODUCTION_MES_JG`

主要来源表：

- `QCM_ZG_JUGDE_APPLY`
- `MCH_TWISTINGLY_RESULT_D`
- `YDM_ZC_STOCKTAKINGLIST`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`

主要查询逻辑：

- 以判定表和加工工艺结果为主
- 结合订单和调差信息汇总加工月报

写入目标：

- `insert into HOT_PRODUCTION_MES_JG`

### 10.2 `mes_cx_rcl_zxnew_hand`
作用：

- 生成热处理生产月报，写入 `HOT_HEAT_PRODUCTION_MES_GX`

主要来源表：

- `QCM_ZG_JUGDE_APPLY`
- `YDM_ZC_STOCKTAKINGLIST`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`

写入目标：

- `insert into HOT_HEAT_PRODUCTION_MES_GX`

### 10.3 `mes_cx_rz_zxnew_hand`
作用：

- 生成热轧生产月报，写入 `HOT_PRODUCTION_MES_RZ`

主要来源表：

- `QCM_ZG_JUGDE_APPLY`
- `YDM_GP_OUTLIST`
- `YDM_ZC_STOCKTAKINGLIST`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`

写入目标：

- `insert into HOT_PRODUCTION_MES_RZ`

## 11. 阶段 4：在产品及结构性结果

### 11.1 `mes_cx_JG_zzpnew_hand`
作用：

- 生成加工在产品及相关结构性结果，写入 `HOT_PRODUCTION_MES_JG`

主要来源表：

- `YDM_HTT_INITIAL`
- `MCH_LOADING_RESULT`
- `PLN_ZY_JGX_M`
- `QCM_ZG_JUGDE_APPLY`
- `QCM_BC_PASS_APPLY`
- `PORT_MCH_BATCH_SAMPLE_RESULT`
- `MCH_TWISTINGLY_RESULT`
- `YDM_ZC_INLIST`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`
- 以及部分热轧成品来源表

月结特点：

- 这类过程通常同时涉及当前月和次月
- 不能把次月逻辑删掉

写入目标：

- `insert into HOT_PRODUCTION_MES_JG`

### 11.2 `mes_cx_rcl_zzpnew_hand`
作用：

- 生成热处理在产品及相关结构性结果，写入 `HOT_HEAT_PRODUCTION_MES_GX`

主要来源表：

- `PLN_ZY_RCL_M`
- `PORT_HTT_BATCH_SAMPLE_RESULT`
- `QCM_ZG_JUGDE_APPLY`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`

写入目标：

- `insert into HOT_HEAT_PRODUCTION_MES_GX`

### 11.3 `mes_cx_rz_zzpnew_hand`
作用：

- 生成热轧在产品及相关结构性结果，写入 `HOT_PRODUCTION_MES_RZ`

主要来源表：

- `YDM_ZC_INITIAL_ZG`
- `PORT_MIL_BATCH_SAMPLE_RESULT`
- `QCM_ZG_JUGDE_APPLY`
- `MIL_PLAN`
- `MIL_SLAB_SCRAP`
- `MIL_FURNACES_RESLUT_DETIA`
- `MIL_OFFLINE_GROUP`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`
- `PLN_ZY_ZG_M`

写入目标：

- `insert into HOT_PRODUCTION_MES_RZ`

### 11.4 `mes_cx_jg_CSJG_HAND`
作用：

- 生成车丝加工相关结果，写入 `HOT_PRODUCTION_MES_JG`

主要来源表：

- `QCM_ZG_JUGDE_APPLY`
- `MCH_TWISTINGLY_RESULT_D`
- `ORDERDETAIL_V@TH_CX_LINK`
- `SLM_ORDER_HEAD`

说明：

- 名称中的 `CSJG` 表示车丝加工相关过程

写入目标：

- `insert into HOT_PRODUCTION_MES_JG`

## 12. 月报与收发存对比口径

### 12.1 半成品与月报对比
半成品与月报对比时，不能直接把半成品入库原表或 `CX_YDM_BC_INLIST` 全量拿去和月报对比。

原因：

- 月报反映的是当月生产形成的产出
- 半成品入库结果里可能混有非当月生产形成的业务类型

本次交接确认的规则：

- `改判入库` 不参与与月报直接对比
- `红冲入库` 不参与与月报直接对比

因此半成品与月报核对时，必须先按入库类型拆开，再决定哪些类型参与比较。
实操上建议先按结果表中的入库类型字段分组，再决定哪些分组参与月报比较。

### 12.2 成品与月报对比
成品与月报对比也遵循同样思路。

本次交接确认的规则：

- `改判入库` 不参与与月报直接对比
- `红冲入库` 不参与与月报直接对比

因此成品月报与成品入库结果核对时，也必须先看入库类型，而不是直接拿结果表全量求和。
实操上建议先按结果表中的入库类型字段分组，再决定哪些分组参与月报比较。

## 13. 建议执行脚本顺序
```sql
-- 阶段1 半成品
begin MES_CX_YDM_BC_INITIAL_hand; end;
/
begin mes_cx_ydm_bc_inlist_csjg_hand; end;
/
begin mes_cx_ydm_bc_inlist_new_hand; end;
/
begin mes_cx_ydm_bc_outlist_csjg; end;
/
begin mes_cx_ydm_bc_outlist_new_hand; end;
/

-- 阶段2 成品
begin mes_cx_ydm_zc_initialnew_hand; end;
/
begin mes_cx_ydm_zc_inlist_new_hand; end;
/
begin mes_cx_ydm_zc_outlist_new_hand; end;
/

-- 阶段3 生产月报
begin mes_cx_jg_zxnew_hand; end;
/
begin mes_cx_rcl_zxnew_hand; end;
/
begin mes_cx_rz_zxnew_hand; end;
/

-- 阶段4 在产品及结构
begin mes_cx_JG_zzpnew_hand; end;
/
begin mes_cx_rcl_zzpnew_hand; end;
/
begin mes_cx_rz_zzpnew_hand; end;
/
begin mes_cx_jg_CSJG_HAND; end;
/
```

## 14. 统一校验

### 14.1 执行校验
```sql
begin
  usp_ValidateProductionData('2026-03');
end;
/
```

### 14.2 查看校验结果
```sql
select problem, yearmonth, material_no, create_time, problem_type
  from DataValidationResult t
 where t.yearmonth = '2026-03';
```

### 14.3 校验入口逻辑
统一校验入口是：

- `usp_ValidateProductionData(p_YearMonth)`

入口逻辑分三步：

1. 先删除 `DataValidationResult` 中当前月份已有的历史校验结果
2. 依次执行各个校验函数
3. 把各类问题数量和总问题数重新写回 `DataValidationResult`

当前入口中实际启用的校验函数有 5 个：

- `validate_inventory_vs_mes`
- `validate_opening_balance`
- `validate_production_report`
- `validate_goods_ledger`
- `validate_material_existence`

代码里还预留了 2 个校验函数，但当前默认未启用：

- `validate_process_chain`
- `validate_group_uniqueness`

因此，如果后面有人说“为什么过程已经存在，但结果里没有这类校验”，首先要确认入口过程里是否真的把该函数打开了。

### 14.4 `validate_inventory_vs_mes`
作用：

- 校验生产月报与成品收发存入库是否一致

主要取数表：

- `cx_ydm_zc_inlist`
- `hot_production_mes_rz`
- `hot_heat_production_mes_gx`
- `hot_production_mes_jg`

取数逻辑：

- 先从 `cx_ydm_zc_inlist` 按 `material_no + process_name` 汇总当月成品入库重量
- 只统计 `act_in_weight > 0` 且 `act_in_count > 0` 的记录
- 再根据 `process_name` 分别去不同月报表取值：
  - `热轧` -> `hot_production_mes_rz`
  - `热处理` -> `hot_heat_production_mes_gx`
  - `加工 / 车丝` -> `hot_production_mes_jg`

当前比较口径：

- 月报使用 `sum(prod_weight - nvl(lc_weight, 0))`
- 成品台账使用 `sum(act_in_weight)`

写入结果：

- 如果两边不等，则写入 `DataValidationResult`
- `problem_type = '生产月报与成品台账差异'`

月结理解要点：

- 这条校验是“月报 vs 成品入库”
- 它不是比成品期初或出库
- 对外解释差异时，必须先明确是否沿用这个净值口径

### 14.5 `validate_opening_balance`
作用：

- 校验台账跨月连续性
- 同时检查成品和半成品

主要取数表：

- 成品：
  - `cx_ydm_zc_initial`
  - `cx_ydm_zc_inlist`
  - `cx_ydm_zc_outlist`
- 半成品：
  - `cx_ydm_bc_initial`
  - `cx_ydm_bc_inlist`
  - `cx_ydm_bc_outlist`

核心公式：

- 本月期初 = 上月期初 + 上月入库 - 上月出库

成品重量口径：

- `上月出库重量 = act_out_weight - nvl(differential, 0)`

半成品重量口径：

- `上月出库重量 = act_out_weight`

还会额外检查：

- 上月有业务，但本月没有期初的物料缺失问题

写入结果：

- 成品和半成品的跨月不连续都会写入 `DataValidationResult`
- `problem_type = '台账期初差异'`

月结理解要点：

- 这是最核心的跨月连续性校验
- 只要月结重建后发现“2 月末不等于 3 月初”这类问题，优先看这一类结果
- 但要注意，这里是按物料汇总口径校验，不等于子炉号明细一定不平

### 14.6 `validate_production_report`
作用：

- 校验生产月报本身字段是否规范

主要取数表：

- `hot_production_mes_rz`
- `hot_heat_production_mes_gx`
- `hot_production_mes_jg`

检查内容：

1. 钢坯编码规则
   - 首字母是否为指定类型
   - 不同类型长度是否符合规则
2. 关键字段是否为空
   - 例如 `RESOURCE_TYPE`
   - `MATE_CODE`
3. 物料名称拆分后是否和月报字段一致
   - `MATE_NAME` 拆分结果
   - 对比 `PROD_VARIETY`
   - 对比 `STEEL_LEVEL`
   - 对比 `STEEL_NO`

写入结果：

- `problem_type` 会落到钢坯编码规则、非空字段校验、物料名称校验等类别

月结理解要点：

- 这条校验不比较台账
- 它是月报自身格式和字段一致性的校验

### 14.7 `validate_goods_ledger`
作用：

- 校验收发存结果表自身字段是否规范

主要取数表：

- 成品：
  - `cx_ydm_zc_initial`
  - `cx_ydm_zc_inlist`
  - `cx_ydm_zc_outlist`
- 半成品：
  - `cx_ydm_bc_initial`
  - `cx_ydm_bc_inlist`
  - `cx_ydm_bc_outlist`

检查内容：

1. 非空字段检查
   - `IS_LLJG`
   - `MATERIAL_NO`
2. 物料名称拆分校验
   - `MATERIAL_NAME` 拆分后
   - 对比 `PRODUCNAME`
   - 对比 `STEELNAME`
   - 对比 `GRADENAME`

写入结果：

- `problem_type` 主要是非空字段校验、物料名称校验

月结理解要点：

- 这条校验的是结果表质量
- 如果字段是空、物料名称拆分不一致，说明生成结果本身不规范

### 14.8 `validate_material_existence`
作用：

- 校验月报里的物料编码是否存在于当月收发存结果中

主要取数表：

- 收发存结果表：
  - `cx_ydm_zc_initial`
  - `cx_ydm_zc_inlist`
  - `cx_ydm_zc_outlist`
  - `cx_ydm_bc_initial`
  - `cx_ydm_bc_inlist`
  - `cx_ydm_bc_outlist`
- 月报结果表：
  - `hot_production_mes_rz`
  - `hot_heat_production_mes_gx`
  - `hot_production_mes_jg`

取数逻辑：

- 先收集当月所有收发存结果表里出现过的 `material_no`
- 再逐个检查月报表中的 `mate_code` 是否包含在这个集合中
- 只检查 `mate_weight <> 0` 且 `prod_type <> '在产品'` 的月报记录

写入结果：

- `problem_type = '物料编码存在性'`

月结理解要点：

- 这条适合发现“月报有，但收发存没有”的物料
- 遇到这类问题时，优先追映射、来源表月份、以及收发存过程是否漏跑

### 14.9 当前默认未启用的两类校验
代码中还存在但默认未在入口中启用的校验：

- `validate_process_chain`
- `validate_group_uniqueness`

交接时要注意：

- 这两类函数如果没有在 `usp_ValidateProductionData` 里打开，就不会产生结果
- 所以后续若有人要增加校验范围，需要同时修改入口过程，而不是只创建函数

## 15. 异常排查顺序

### 15.1 先看是否重复重跑
先确认是否存在以下情况：

- 没先删结果表就重跑过程
- job 在后台又自动重写了一轮
- 同月跑了多轮，结果叠加

### 15.2 再看过程月份
重点确认：

- 是否有过程仍停留在旧月份
- 在产品过程是否误删了次月逻辑

### 15.3 再看是否残留临时过滤
重点检查：

- 是否有临时炉号条件没有注释
- 是否把全量月结误缩成了补数月结

### 15.4 再看来源表
来源表排查时要注意：

- 原表月份是否挂错
- 是否存在跨月残留
- 是否存在改判、红冲等不应直接参与月报对比的记录

### 15.5 再看映射逻辑
很多结果不是直接拿原表 `material_no`，而是：

- 炉号
- 反查合同
- 合同映射物料编码

所以遇到物料对不上时，不要只按原表物料编码查，必须把炉号、合同、映射链一起看。

### 15.6 最后看校验口径
很多问题不是数据真错，而是对比口径不一致。  
特别是月报与收发存对比时，要先确认比较范围和业务类型。

## 16. 交接时必须提醒的事项

- 月结前先停 job
- 月结前先确认过程月份
- 月结前先确认没有临时炉号条件
- 删的是结果表，不是来源表
- `*_CSJG_*` 过程应理解为车丝加工相关过程
- `_NEW_HAND` 不要单凭名字判断业务口径，必须以 SQL 取数条件为准
- 半成品与成品和月报对比时，改判、红冲不直接参与对比
- 在产品过程自带跨月逻辑，不能机械把所有月份都改成当前月

## 17. 建议交接时一并保留的文件

- 本文档
- 当月过程调整脚本
- 当月执行脚本
- 校验 SQL
- 结果查询 SQL

这样后续接手人只需要确认：

1. 本次跑的是哪一个月份
2. 当前月和次月分别是多少
3. 是否还有临时过滤条件未清理

即可继续完成月结。
