| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- -- ============================================================================
- -- 1.0.553 · 补 mdp_inbound_grant 缺失的唯一键 uk_inbound_grant(access_key, entity_code)
- --
- -- 背景:1.0.536 里这张表是 CREATE TABLE IF NOT EXISTS。在 1.0.536 正式执行之前,
- -- 该表已被某个实例的 SqlSugar CodeFirst 抢先建出(CodeFirst 在容器初始化阶段跑,
- -- 早于 UseAutoVersionUpdate 中间件),于是 1.0.536 的建表语句整条 no-op,
- -- 脚本里声明的 UNIQUE KEY 从未落地。实测证据:该表无任何 COLUMN COMMENT、
- -- 无 DEFAULT,status 是 int 而非脚本声明的 tinyint —— 全是 CodeFirst 产物特征。
- --
- -- 为什么必须补:mdp_inbound_grant 是第三方推数入站的授权表。
- -- (access_key, entity_code) 是它的业务身份:同一凭证对同一实体只应有一条授权。
- -- 缺了这个唯一键,重复授权行可以写进去,而入站鉴权按该组合查授权,
- -- 出现两条就意味着限流配额、IP 白名单、batch 上限到底以哪条为准是不确定的。
- --
- -- 本脚本只做这一件事。刻意不碰 status 的类型与 DEFAULT、不碰其余四张 inbound 表 ——
- -- 那些是等价差异,不影响业务语义,混在一起改会让这次热修的回滚面无谓扩大。
- --
- -- 幂等与安全:
- -- · 索引不存在 → 创建
- -- · 已存在且定义正确 → no-op
- -- · 同名但定义不对 → SIGNAL 中止,绝不 DROP 重建(可能是别人有意改过)
- -- · 存在重复数据 → SIGNAL 中止(加唯一键会失败,提前给出可读原因)
- --
- -- AutoVersionUpdate 按分号拆句、无事务,故全部用 PREPARE/EXECUTE 自包含,
- -- 且注释内不出现会被 parser 误切的分号模式。
- -- ============================================================================
- -- ── 前置门禁 1:不能有重复数据,否则加唯一键必然失败 ────────────────────────
- SET @dup_groups := (
- SELECT COUNT(*) FROM (
- SELECT 1 FROM `mdp_inbound_grant` GROUP BY `access_key`, `entity_code` HAVING COUNT(*) > 1
- ) d
- );
- SET @sql := IF(@dup_groups <> 0,
- "SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '1.0.553-G1: mdp_inbound_grant 存在重复 (access_key, entity_code),无法建唯一键 — 先人工裁决保留哪条'",
- 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ── 前置门禁 2:同名索引若已存在,定义必须完全正确,否则中止 ────────────────
- SET @idx_cols := (
- SELECT GROUP_CONCAT(`COLUMN_NAME` ORDER BY `SEQ_IN_INDEX` SEPARATOR ',')
- FROM information_schema.`STATISTICS`
- WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_inbound_grant'
- AND `INDEX_NAME` = 'uk_inbound_grant'
- );
- SET @idx_unique := (
- SELECT MIN(`NON_UNIQUE`) FROM information_schema.`STATISTICS`
- WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_inbound_grant'
- AND `INDEX_NAME` = 'uk_inbound_grant'
- );
- SET @sql := IF(@idx_cols IS NOT NULL
- AND (@idx_cols <> 'access_key,entity_code' OR @idx_unique <> 0),
- "SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '1.0.553-G2: uk_inbound_grant 已存在但定义不符预期 — 中止,不自动 DROP 重建'",
- 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ── 主体:不存在才创建 ──────────────────────────────────────────────────────
- SET @sql := IF(@idx_cols IS NULL,
- 'ALTER TABLE `mdp_inbound_grant` ADD UNIQUE KEY `uk_inbound_grant` (`access_key`, `entity_code`)',
- 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ── 结果断言:执行完必须存在且定义正确 ──────────────────────────────────────
- SET @after_cols := (
- SELECT GROUP_CONCAT(`COLUMN_NAME` ORDER BY `SEQ_IN_INDEX` SEPARATOR ',')
- FROM information_schema.`STATISTICS`
- WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'mdp_inbound_grant'
- AND `INDEX_NAME` = 'uk_inbound_grant' AND `NON_UNIQUE` = 0
- );
- SET @sql := IF(IFNULL(@after_cols, '') <> 'access_key,entity_code',
- "SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '1.0.553-A1: uk_inbound_grant 建后校验失败'",
- 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- SELECT @after_cols AS uk_inbound_grant_columns;
|