-- ============================================ -- 演示环境种子库结构补齐(2026-10-16) -- 背景:mysql-init/01-schema.sql 源自 db_iotlcm_init.sql(较旧), -- 与当前业务镜像期望的 schema 存在差异,导致 app-server 后台任务 -- 报 `Unknown column 'source_channel'` 等错误。 -- 依据:以预演1(内网环境)的 db_iotlcm 为基准逐列比对得出。 -- 差异:缺 1 张表(card_channel_assoc)+ 27 列(分布 8 张表)。 -- -- ⚠️ MySQL 8.0 不支持 `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`(MariaDB 语法), -- 因此用存储过程按 information_schema 判断后动态执行,保证幂等、可重复运行。 -- -- 执行顺序:01-schema.sql → 本文件(按文件名排序,02-)。 -- ============================================ SET NAMES utf8mb4; USE `db_iotlcm`; -- ---------- 1. 缺失的表:card_channel_assoc(卡号段-通道关联)---------- CREATE TABLE IF NOT EXISTS `card_channel_assoc` ( `id` bigint NOT NULL AUTO_INCREMENT, `channel_id` int NOT NULL COMMENT '通道ID', `match_type` tinyint NOT NULL COMMENT '匹配类型', `iccid` varchar(32) DEFAULT NULL COMMENT '单卡ICCID', `iccid_start` varchar(32) DEFAULT NULL COMMENT '卡号段起始', `iccid_end` varchar(32) DEFAULT NULL COMMENT '卡号段结束', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态', `remark` varchar(255) DEFAULT NULL COMMENT '备注', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_channel_id` (`channel_id`), KEY `idx_iccid` (`iccid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='卡号段与通道关联'; -- ---------- 2. 幂等补列辅助过程 ---------- DROP PROCEDURE IF EXISTS `sp_add_column_if_missing`; DELIMITER $$ CREATE PROCEDURE `sp_add_column_if_missing`( IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_ddl TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = p_table AND column_name = p_column ) THEN SET @s = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN ', p_ddl); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT CONCAT('added ', p_table, '.', p_column) AS action; ELSE SELECT CONCAT('exists ', p_table, '.', p_column) AS action; END IF; END$$ DELIMITER ; -- ---------- 3. batch_main:补 2 列 ---------- CALL sp_add_column_if_missing('batch_main', 'source_channel', "`source_channel` varchar(24) NOT NULL DEFAULT 'legacy' COMMENT '发起渠道:console/mini_program/api/system/legacy'"); CALL sp_add_column_if_missing('batch_main', 'execution_mode', "`execution_mode` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '执行模式'"); -- ---------- 4. sys_user:补 1 列 ---------- CALL sp_add_column_if_missing('sys_user', 'is_init_password', "`is_init_password` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否为初始密码'"); -- ---------- 5. t_sim_card_info:补 4 列 ---------- CALL sp_add_column_if_missing('t_sim_card_info', 'imei_sync_time', "`imei_sync_time` datetime DEFAULT NULL COMMENT 'IMEI 同步时间'"); CALL sp_add_column_if_missing('t_sim_card_info', 'imei_update_time', "`imei_update_time` datetime DEFAULT NULL COMMENT 'IMEI 更新时间'"); CALL sp_add_column_if_missing('t_sim_card_info', 'traffic_cutoff_triggered_at', "`traffic_cutoff_triggered_at` datetime DEFAULT NULL COMMENT '流量停机触发时间'"); CALL sp_add_column_if_missing('t_sim_card_info', 'traffic_cutoff_cross_month_hold', "`traffic_cutoff_cross_month_hold` tinyint(1) NOT NULL DEFAULT 0 COMMENT '流量停机跨月保持'"); -- ---------- 6. t_sim_channels:补 9 列 ---------- CALL sp_add_column_if_missing('t_sim_channels', 'app_key', "`app_key` varchar(64) DEFAULT NULL COMMENT '运营商 app_key'"); CALL sp_add_column_if_missing('t_sim_channels', 'app_secret', "`app_secret` varchar(64) DEFAULT NULL COMMENT '运营商 app_secret'"); CALL sp_add_column_if_missing('t_sim_channels', 'operator', "`operator` tinyint unsigned DEFAULT NULL COMMENT '运营商'"); CALL sp_add_column_if_missing('t_sim_channels', 'is_normal', "`is_normal` tinyint(1) DEFAULT NULL COMMENT '是否正常'"); CALL sp_add_column_if_missing('t_sim_channels', 'docking_status', "`docking_status` tinyint(1) DEFAULT NULL COMMENT '对接状态'"); CALL sp_add_column_if_missing('t_sim_channels', 'sync_enabled', "`sync_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否启用全量同步'"); CALL sp_add_column_if_missing('t_sim_channels', 'card_info_count', "`card_info_count` bigint NOT NULL DEFAULT 0 COMMENT '卡信息数量'"); CALL sp_add_column_if_missing('t_sim_channels', 'stock_card_count', "`stock_card_count` bigint NOT NULL DEFAULT 0 COMMENT '库存卡数量'"); CALL sp_add_column_if_missing('t_sim_channels', 'cancellation_card_count', "`cancellation_card_count` bigint NOT NULL DEFAULT 0 COMMENT '销户卡数量'"); -- ---------- 7. 两张套餐绑定表:补 batch_no ---------- CALL sp_add_column_if_missing('t_sim_pool_bind_package', 'batch_no', "`batch_no` varchar(64) NOT NULL DEFAULT '' COMMENT '批次号'"); CALL sp_add_column_if_missing('t_sim_pool_bind_pkg_logs', 'batch_no', "`batch_no` varchar(64) NOT NULL DEFAULT '' COMMENT '批次号'"); -- ---------- 8. 清理辅助过程 ---------- DROP PROCEDURE IF EXISTS `sp_add_column_if_missing`; -- ---------- 9. 校验 ---------- SELECT 'tables' AS check_item, COUNT(*) AS n FROM information_schema.tables WHERE table_schema='db_iotlcm' UNION ALL SELECT 'columns', COUNT(*) FROM information_schema.columns WHERE table_schema='db_iotlcm' UNION ALL SELECT 'has_source_channel', COUNT(*) FROM information_schema.columns WHERE table_schema='db_iotlcm' AND table_name='batch_main' AND column_name='source_channel' UNION ALL SELECT 'has_card_channel_assoc', COUNT(*) FROM information_schema.tables WHERE table_schema='db_iotlcm' AND table_name='card_channel_assoc';