-- 二期库位共享溢出位 A0 增量迁移。 -- 执行顺序:phase2-pallet-location-schema.sql、本文件。 -- 普通库位仍保持一托一位;同一租户仓库只有一个 A0,且 A0 可承载多个活动资源。 SET NAMES utf8mb4; USE baiyue_warehouse; DROP PROCEDURE IF EXISTS add_location_overflow_column_if_missing; DELIMITER $$ CREATE PROCEDURE add_location_overflow_column_if_missing( IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64), IN p_column_definition TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = p_table_name AND column_name = p_column_name ) THEN SET @column_sql = CONCAT( 'ALTER TABLE `', REPLACE(p_table_name, '`', '``'), '` ADD COLUMN `', REPLACE(p_column_name, '`', '``'), '` ', p_column_definition ); PREPARE column_statement FROM @column_sql; EXECUTE column_statement; DEALLOCATE PREPARE column_statement; END IF; END$$ DELIMITER ; CALL add_location_overflow_column_if_missing( 'wh_location', 'shared_overflow', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否为系统共享溢出位 A0'' AFTER max_weight_kg' ); CALL add_location_overflow_column_if_missing( 'wh_location_reservation', 'shared_overflow', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否使用共享溢出位 A0'' AFTER location_code' ); CALL add_location_overflow_column_if_missing( 'wh_location_occupancy', 'shared_overflow', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否使用共享溢出位 A0'' AFTER location_code' ); -- 兼容迁移前人工或旧流程已创建的 A0,并将资源快照回填一致。 UPDATE wh_location SET shared_overflow = 1, status = 'AVAILABLE' WHERE location_code = 'A0' AND deleted = 0; UPDATE wh_location_reservation r JOIN wh_location l ON l.tenant_id = r.tenant_id AND l.id = r.location_id SET r.shared_overflow = l.shared_overflow; UPDATE wh_location_occupancy o JOIN wh_location l ON l.tenant_id = o.tenant_id AND l.id = o.location_id SET o.shared_overflow = l.shared_overflow; DROP PROCEDURE IF EXISTS add_location_overflow_column_if_missing; -- 先移除依赖旧生成列的唯一索引,再按普通库位/A0 的不同语义重建。 SET @schema_name = DATABASE(); SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_reservation' AND index_name = 'uk_location_active_reservation') > 0, 'ALTER TABLE wh_location_reservation DROP INDEX uk_location_active_reservation', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_reservation' AND index_name = 'uk_pallet_active_reservation') > 0, 'ALTER TABLE wh_location_reservation DROP INDEX uk_pallet_active_reservation', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; ALTER TABLE wh_location_reservation MODIFY COLUMN active_reservation TINYINT GENERATED ALWAYS AS ( CASE WHEN reservation_status = 'RESERVED' AND shared_overflow = 0 THEN 1 ELSE NULL END ) STORED COMMENT '普通库位活动预占唯一标记,A0 返回 NULL'; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_reservation' AND index_name = 'uk_location_active_reservation') = 0, 'ALTER TABLE wh_location_reservation ADD UNIQUE KEY uk_location_active_reservation (tenant_id, location_id, active_reservation)', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_occupancy' AND index_name = 'uk_location_active_occupancy') > 0, 'ALTER TABLE wh_location_occupancy DROP INDEX uk_location_active_occupancy', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_occupancy' AND index_name = 'uk_pallet_active_occupancy') > 0, 'ALTER TABLE wh_location_occupancy DROP INDEX uk_pallet_active_occupancy', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; DROP PROCEDURE IF EXISTS add_location_overflow_column_if_missing; DELIMITER $$ CREATE PROCEDURE add_location_overflow_column_if_missing( IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64), IN p_column_definition TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = p_table_name AND column_name = p_column_name ) THEN SET @column_sql = CONCAT( 'ALTER TABLE `', REPLACE(p_table_name, '`', '``'), '` ADD COLUMN `', REPLACE(p_column_name, '`', '``'), '` ', p_column_definition ); PREPARE column_statement FROM @column_sql; EXECUTE column_statement; DEALLOCATE PREPARE column_statement; END IF; END$$ DELIMITER ; CALL add_location_overflow_column_if_missing( 'wh_location_reservation', 'active_pallet_reservation', 'TINYINT GENERATED ALWAYS AS (CASE WHEN reservation_status = ''RESERVED'' THEN 1 ELSE NULL END) STORED COMMENT ''托盘活动预占唯一标记(包含 A0)''' ); CALL add_location_overflow_column_if_missing( 'wh_location_occupancy', 'active_location_occupancy', 'TINYINT GENERATED ALWAYS AS (CASE WHEN occupancy_status = ''OCCUPIED'' AND shared_overflow = 0 THEN 1 ELSE NULL END) STORED COMMENT ''普通库位活动占用唯一标记''' ); CALL add_location_overflow_column_if_missing( 'wh_location_occupancy', 'active_pallet_occupancy', 'TINYINT GENERATED ALWAYS AS (CASE WHEN occupancy_status = ''OCCUPIED'' THEN 1 ELSE NULL END) STORED COMMENT ''托盘活动占用唯一标记(包含 A0)''' ); DROP PROCEDURE IF EXISTS add_location_overflow_column_if_missing; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_reservation' AND index_name = 'uk_pallet_active_reservation') = 0, 'ALTER TABLE wh_location_reservation ADD UNIQUE KEY uk_pallet_active_reservation (tenant_id, pallet_id, active_pallet_reservation)', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_occupancy' AND index_name = 'uk_location_active_occupancy') = 0, 'ALTER TABLE wh_location_occupancy ADD UNIQUE KEY uk_location_active_occupancy (tenant_id, location_id, active_location_occupancy)', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement; SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = @schema_name AND table_name = 'wh_location_occupancy' AND index_name = 'uk_pallet_active_occupancy') = 0, 'ALTER TABLE wh_location_occupancy ADD UNIQUE KEY uk_pallet_active_occupancy (tenant_id, pallet_id, active_pallet_occupancy)', 'SELECT 1'); PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement;