| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- -- ============================================================================
- -- S6-DISPLAY-FIX-B1 · D-04 存量订正:mdp_std_ipqc_inspection 字面量 'null' → SQL NULL
- --
- -- 背景(根因已在同批代码修复):
- -- IpqcInspectionMdpSyncService.TransformHeadStandardAsync 原先对字符串列使用裸
- -- JSON_UNQUOTE(JSON_EXTRACT(raw_data,'$.x'))。MySQL 下 JSON null 经 JSON_UNQUOTE
- -- 会产出**长度为 4 的字面量字符串 'null'**(实测:其 IS NULL = 0),
- -- 于是 API 返回 "formNo":"null",前端 `|| '-'` 兜底对真值字符串无效,页面直接显示 null。
- -- 同文件的 detail transform 因使用 MdpJsonSql.Str()(= NULLIF(...,'null'))从未受影响。
- -- 代码侧已改为统一走 MdpJsonSql.Str/Dec/DateTimeSec,此后不再产生新污染;
- -- 本脚本只订正**已经落库的存量**。
- --
- -- 证据(aidopdev,2026-09-02 只读取证):
- -- ① 受影响 10 列,7/8 行命中(form_no / version_no / inspec_standard_code /
- -- inspec_standard_version / production_person / attachment 各 7 行,remark 3 行,
- -- process_code / process_name / production_work_order 各 2 行)。
- -- ② 逐行 JOIN 回源表 qms_gcjyd 证明:凡 STD 为 'null' 者,其源列**均为 SQL NULL**,
- -- 不存在"业务真的存了文本 null"的反例。
- -- ③ 全表扫描 qms_gcjyd 的 17 个对应源列,**没有任何一列持有字面量文本 'null'**。
- -- 故 'null' 100% 来自转换污染,可安全归一为 SQL NULL。
- --
- -- 写入范围(INSERT 0 · UPDATE ≤8 行 · DELETE 0 · DDL 0):
- -- 表:mdp_std_ipqc_inspection(仅标准层,不碰任何业务源表)
- -- 列白名单(10 列,均为可空展示列;不含 NOT NULL 列,不含身份键):
- -- attachment, form_no, inspec_standard_code, inspec_standard_version,
- -- process_code, process_name, production_person, production_work_order,
- -- remark, version_no
- -- 行范围:仅限**能回溯到源单**的行(EXISTS qms_gcjyd 同 id 同 tenant_id)。
- --
- -- 刻意不处理(无法自证,遵循"证明不了就不清洗"):
- -- 2 行孤儿 STD(source_row_id 在 qms_gcjyd 无对应行)——
- -- id=22(source_system=WMS_API 契约测试夹具,tenant 1300000000001)与
- -- id=32(tenant_id=0,本身即已知脏行)。
- -- 这两行的贴源记录仍在 mdp_stg_ipqc_pull 中,**下一次 inbound 会由已修复的转换代码
- -- 自动 upsert 订正**,无需在此强行 UPDATE。
- --
- -- 幂等:WHERE col='null' 决定重复执行为 0 行影响。
- -- 回滚:本操作把污染值归一为源真值(NULL),属**数据订正而非数据变更**,不提供反向脚本
- -- (反向写回 'null' 只会复原缺陷)。如确需还原,可对同一行集执行
- -- UPDATE ... SET col='null' WHERE col IS NULL,但需先确认该列源值确为 NULL。
- -- ============================================================================
- -- ── 执行前计数(期望:与上文证据一致)──
- SELECT 'BEFORE' AS phase,
- SUM(attachment = 'null') AS attachment,
- SUM(form_no = 'null') AS form_no,
- SUM(inspec_standard_code = 'null') AS inspec_standard_code,
- SUM(inspec_standard_version = 'null') AS inspec_standard_version,
- SUM(process_code = 'null') AS process_code,
- SUM(process_name = 'null') AS process_name,
- SUM(production_person = 'null') AS production_person,
- SUM(production_work_order = 'null') AS production_work_order,
- SUM(remark = 'null') AS remark,
- SUM(version_no = 'null') AS version_no
- FROM mdp_std_ipqc_inspection;
- -- ── 订正:仅可回溯到源单的行,且仅当该列恰为字面量 'null' ──
- UPDATE mdp_std_ipqc_inspection m
- SET m.attachment = NULLIF(m.attachment, 'null'),
- m.form_no = NULLIF(m.form_no, 'null'),
- m.inspec_standard_code = NULLIF(m.inspec_standard_code, 'null'),
- m.inspec_standard_version = NULLIF(m.inspec_standard_version, 'null'),
- m.process_code = NULLIF(m.process_code, 'null'),
- m.process_name = NULLIF(m.process_name, 'null'),
- m.production_person = NULLIF(m.production_person, 'null'),
- m.production_work_order = NULLIF(m.production_work_order, 'null'),
- m.remark = NULLIF(m.remark, 'null'),
- m.version_no = NULLIF(m.version_no, 'null')
- WHERE EXISTS (
- SELECT 1 FROM qms_gcjyd s
- WHERE s.id = m.source_row_id AND s.tenant_id = m.tenant_id
- )
- AND (m.attachment = 'null' OR m.form_no = 'null'
- OR m.inspec_standard_code = 'null' OR m.inspec_standard_version = 'null'
- OR m.process_code = 'null' OR m.process_name = 'null'
- OR m.production_person = 'null' OR m.production_work_order = 'null'
- OR m.remark = 'null' OR m.version_no = 'null');
- -- ── 执行后计数(期望:可回溯行全部归零;仅可能残留上文声明的 2 行孤儿)──
- SELECT 'AFTER' AS phase,
- SUM(attachment = 'null') AS attachment,
- SUM(form_no = 'null') AS form_no,
- SUM(inspec_standard_code = 'null') AS inspec_standard_code,
- SUM(inspec_standard_version = 'null') AS inspec_standard_version,
- SUM(process_code = 'null') AS process_code,
- SUM(process_name = 'null') AS process_name,
- SUM(production_person = 'null') AS production_person,
- SUM(production_work_order = 'null') AS production_work_order,
- SUM(remark = 'null') AS remark,
- SUM(version_no = 'null') AS version_no
- FROM mdp_std_ipqc_inspection;
|