-- ============================================================================= -- 1.0.442 S5 MissedPrint 租户归属回填(一次性数据修复) -- -- 背景 -- MissedPrint(送货标签/箱码)由 SupplierShipmentService「生成标签」写入, -- 历史实现的 INSERT 未写 tenant_id,导致库中 152 行全部为 NULL, -- 下游 FUNC-S5-008 标签查询 / FUNC-S5-013 盘点结果无法按租户过滤, -- UATAdminA 登录可看到 797 租户的 104 行(已确认的跨租户读取)。 -- 代码侧已在同批修复:INSERT 补 tenant_id、MdpHotWatch 的 UPDATE 补租户条件、 -- 008/013 查询补 m.tenant_id = @TenantId。本脚本负责历史行回填。 -- -- 归属推导(唯一 SET 源:scm_shd.tenant_id) -- MissedPrint.ShipperNbr = scm_shd.shddh → scm_shd.tenant_id -- * 不用 Domain 推导:797 与 UAT 的 Domain 同为 8010,Domain 不是租户边界。 -- * 不用 scm_shbq 作 SET 源:它只是标签明细的旁证,覆盖不全(22 行无对应箱码行)。 -- -- 回填前实测(2026-09-01,aidopdev) -- G1 MissedPrint 152 行,tenant_id 全部为 NULL -- G2 scm_shd 中 shddh 解析出多个 tenant_id 的:0(映射无歧义) -- G3 152 行全部可解析,不可解析 0 -- G4 分布:797403760988229 = 104 / 838257186181189 = 48 / 其它 0 / 合计 152 -- G5 scm_shd.tenant_id 为 NULL 或 0 的行:0 -- G6 交叉验证 CreateUser → SysUser.TenantId:一致 152,矛盾 0 -- G7 交叉验证 scm_shbq.xh = MissedPrint.BarCode:一致 130,矛盾 0,无对应 22 -- -- 幂等 -- 仅更新 tenant_id IS NULL 的行;重复执行影响 0 行。 -- ============================================================================= -- 幂等前置:列不存在时补列(正常情况下列已存在,此处只做保险) SET @col_exists := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'MissedPrint' AND COLUMN_NAME = 'tenant_id'); SET @sql := IF(@col_exists = 0, 'ALTER TABLE MissedPrint ADD COLUMN tenant_id BIGINT NULL COMMENT ''租户Id''', 'SELECT 1'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 回填:唯一 SET 源 = scm_shd.tenant_id UPDATE MissedPrint m JOIN ( SELECT shddh, MIN(tenant_id) AS tenant_id FROM scm_shd WHERE tenant_id IS NOT NULL AND tenant_id > 0 GROUP BY shddh HAVING COUNT(DISTINCT tenant_id) = 1 -- 有歧义的单号一律跳过,不猜 ) d ON d.shddh = m.ShipperNbr SET m.tenant_id = d.tenant_id WHERE m.tenant_id IS NULL; -- 幂等:只补空,绝不覆盖已有归属 -- 结果门禁在 1.0.442.verify.sql:still_null=0 / 797=104 / UAT=48 / 合计=152 / 与两路独立推导零矛盾。 -- 若 verify 未过(例如回填前又新增了标签),AutoVersionUpdate 会抛错阻断启动 —— 这是有意的: -- 应先核对新行的归属再决定是否放宽 verify 中的数量断言,而不是让归属不明的行悄悄进库。