Files
BMS/bms-back/sql/customer+supplier/20261104_customer_area_rename.sql
2026-11-04 18:29:47 +08:00

174 lines
9.0 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- 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;