-- Unified migration: ctr_customer.area_type -> customer_area and data_area_type -> customer_area. -- Target: MySQL 5.7.x; run the whole file against the intended database in one connection. -- Confirm both migration_status and dictionary_migration_status report READY. -- Conflicting columns or dictionary values are preserved and reported for manual review. SET @customer_table_exists := ( SELECT COUNT(1) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ctr_customer' ); SET @customer_area_old_exists := ( SELECT COUNT(1) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ctr_customer' AND COLUMN_NAME = 'area_type' ); SET @customer_area_new_exists := ( SELECT COUNT(1) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ctr_customer' AND COLUMN_NAME = 'customer_area' ); SET @customer_area_conflict_count := 0; -- If both columns exist, require matching non-NULL values before merging and dropping the old column. SET @customer_area_check_sql := IF( @customer_area_old_exists = 1 AND @customer_area_new_exists = 1, 'SELECT COUNT(1) INTO @customer_area_conflict_count FROM `ctr_customer` WHERE `area_type` IS NOT NULL AND `customer_area` IS NOT NULL AND BINARY `area_type` <> BINARY `customer_area`', 'SELECT 0 INTO @customer_area_conflict_count' ); PREPARE customer_area_stmt FROM @customer_area_check_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; -- In the no-conflict dual-column state, copy values that only exist in the old column. SET @customer_area_merge_sql := IF( @customer_area_old_exists = 1 AND @customer_area_new_exists = 1 AND @customer_area_conflict_count = 0, 'UPDATE `ctr_customer` SET `customer_area` = `area_type` WHERE `customer_area` IS NULL AND `area_type` IS NOT NULL', 'SELECT 1' ); PREPARE customer_area_stmt FROM @customer_area_merge_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; -- Drop the legacy column only after its values have been merged without conflicts. SET @customer_area_drop_sql := IF( @customer_area_old_exists = 1 AND @customer_area_new_exists = 1 AND @customer_area_conflict_count = 0, 'ALTER TABLE `ctr_customer` DROP COLUMN `area_type`', 'SELECT 1' ); PREPARE customer_area_stmt FROM @customer_area_drop_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; -- Rename the existing column, or create the new column when neither name exists. SET @customer_area_rename_sql := CASE WHEN @customer_table_exists = 1 AND @customer_area_old_exists = 1 AND @customer_area_new_exists = 0 THEN 'ALTER TABLE `ctr_customer` CHANGE COLUMN `area_type` `customer_area` varchar(32) DEFAULT NULL COMMENT ''客户区域(字典 customer_area)'' AFTER `customer_type`' WHEN @customer_table_exists = 1 AND @customer_area_old_exists = 0 AND @customer_area_new_exists = 0 THEN 'ALTER TABLE `ctr_customer` ADD COLUMN `customer_area` varchar(32) DEFAULT NULL COMMENT ''客户区域(字典 customer_area)'' AFTER `customer_type`' ELSE 'SELECT 1' END; PREPARE customer_area_stmt FROM @customer_area_rename_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; SET @customer_area_old_exists := ( SELECT COUNT(1) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ctr_customer' AND COLUMN_NAME = 'area_type' ); SET @customer_area_new_exists := ( SELECT COUNT(1) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ctr_customer' AND COLUMN_NAME = 'customer_area' ); SELECT CASE WHEN @customer_table_exists = 0 THEN 'ERROR: ctr_customer table does not exist in the selected database' WHEN @customer_area_old_exists = 0 AND @customer_area_new_exists = 1 THEN 'READY' WHEN @customer_area_conflict_count > 0 THEN 'BLOCKED: resolve conflicting values and rerun this full script' ELSE 'ERROR: expected customer_area and no area_type; inspect the table before continuing' END AS migration_status, @customer_area_conflict_count AS conflicting_rows; SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ctr_customer' AND COLUMN_NAME IN ('area_type', 'customer_area') ORDER BY ORDINAL_POSITION; -- When migration_status is BLOCKED, inspect these rows, resolve each value manually, then rerun this file. SET @customer_area_conflict_rows_sql := IF( @customer_area_conflict_count > 0, 'SELECT `customer_id`, `customer_code`, `area_type`, `customer_area` FROM `ctr_customer` WHERE `area_type` IS NOT NULL AND `customer_area` IS NOT NULL AND BINARY `area_type` <> BINARY `customer_area` ORDER BY `customer_id`', 'SELECT ''No conflicting customer area values'' AS conflict_check' ); PREPARE customer_area_stmt FROM @customer_area_conflict_rows_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; -- Rename the dictionary identifier and its values. If both dictionary types already exist, -- or both dictionaries use the same value, stop and report instead of creating ambiguity. SET @customer_area_old_dict_exists := ( SELECT COUNT(1) FROM `sys_dict_type` WHERE `dict_type` = 'data_area_type' ); SET @customer_area_new_dict_exists := ( SELECT COUNT(1) FROM `sys_dict_type` WHERE `dict_type` = 'customer_area' ); SET @customer_area_dict_value_conflicts := ( SELECT COUNT(1) FROM `sys_dict_data` old_data JOIN `sys_dict_data` new_data ON old_data.`dict_value` = new_data.`dict_value` WHERE old_data.`dict_type` = 'data_area_type' AND new_data.`dict_type` = 'customer_area' ); SET @customer_area_dict_data_sql := IF( @customer_area_old_exists = 0 AND @customer_area_new_exists = 1 AND (@customer_area_old_dict_exists = 1 OR @customer_area_new_dict_exists = 1) AND @customer_area_dict_value_conflicts = 0 AND NOT (@customer_area_old_dict_exists = 1 AND @customer_area_new_dict_exists = 1), 'UPDATE `sys_dict_data` SET `dict_type` = ''customer_area'' WHERE `dict_type` = ''data_area_type''', 'SELECT 1' ); PREPARE customer_area_stmt FROM @customer_area_dict_data_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; SET @customer_area_dict_type_sql := CASE WHEN @customer_area_old_exists = 0 AND @customer_area_new_exists = 1 AND @customer_area_old_dict_exists = 1 AND @customer_area_new_dict_exists = 0 AND @customer_area_dict_value_conflicts = 0 THEN 'UPDATE `sys_dict_type` SET `dict_type` = ''customer_area'', `dict_name` = ''客户区域'', `update_time` = NOW() WHERE `dict_type` = ''data_area_type''' WHEN @customer_area_old_exists = 0 AND @customer_area_new_exists = 1 AND @customer_area_old_dict_exists = 0 AND @customer_area_new_dict_exists = 1 AND @customer_area_dict_value_conflicts = 0 THEN 'UPDATE `sys_dict_type` SET `dict_name` = ''客户区域'', `update_time` = NOW() WHERE `dict_type` = ''customer_area''' ELSE 'SELECT 1' END; PREPARE customer_area_stmt FROM @customer_area_dict_type_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt; SET @customer_area_old_dict_exists := ( SELECT COUNT(1) FROM `sys_dict_type` WHERE `dict_type` = 'data_area_type' ); SET @customer_area_new_dict_exists := ( SELECT COUNT(1) FROM `sys_dict_type` WHERE `dict_type` = 'customer_area' ); SELECT CASE WHEN @customer_area_old_exists <> 0 OR @customer_area_new_exists <> 1 THEN 'BLOCKED: finish customer column migration first' WHEN @customer_area_old_dict_exists = 0 AND @customer_area_new_dict_exists = 1 AND @customer_area_dict_value_conflicts = 0 THEN 'READY' WHEN @customer_area_old_dict_exists = 1 AND @customer_area_new_dict_exists = 1 THEN 'BLOCKED: both dictionary types exist; merge them manually' WHEN @customer_area_dict_value_conflicts > 0 THEN 'BLOCKED: dictionary values overlap; reconcile them manually' ELSE 'MISSING: verify the customer area dictionary in the selected database' END AS dictionary_migration_status, @customer_area_dict_value_conflicts AS overlapping_values; SELECT `dict_id`, `dict_name`, `dict_type`, `status` FROM `sys_dict_type` WHERE `dict_type` IN ('data_area_type', 'customer_area') ORDER BY `dict_id`; SELECT `dict_code`, `dict_type`, `dict_value`, `dict_label`, `status` FROM `sys_dict_data` WHERE `dict_type` IN ('data_area_type', 'customer_area') ORDER BY `dict_type`, `dict_sort`, `dict_code`; SET @customer_area_dict_conflict_rows_sql := IF( @customer_area_dict_value_conflicts > 0, 'SELECT old_data.`dict_value`, old_data.`dict_label` AS old_label, new_data.`dict_label` AS new_label FROM `sys_dict_data` old_data JOIN `sys_dict_data` new_data ON old_data.`dict_value` = new_data.`dict_value` WHERE old_data.`dict_type` = ''data_area_type'' AND new_data.`dict_type` = ''customer_area'' ORDER BY old_data.`dict_value`', 'SELECT ''No overlapping dictionary values'' AS conflict_check' ); PREPARE customer_area_stmt FROM @customer_area_dict_conflict_rows_sql; EXECUTE customer_area_stmt; DEALLOCATE PREPARE customer_area_stmt;