CREATE TABLE IF NOT EXISTS po_purchase_order_sales_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, purchase_order_id BIGINT NOT NULL, sales_order_id BIGINT NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uq_po_so_link (purchase_order_id, sales_order_id), KEY idx_po_so_link_so (sales_order_id), CONSTRAINT fk_po_so_link_po FOREIGN KEY (purchase_order_id) REFERENCES po_purchase_order(id) ON DELETE CASCADE, CONSTRAINT fk_po_so_link_so FOREIGN KEY (sales_order_id) REFERENCES so_sales_order(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; SET @idx_wh_stock_lot_item_lot_no_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wh_stock_lot' AND INDEX_NAME = 'idx_wh_stock_lot_item_lot_no' ); SET @idx_wh_stock_lot_item_lot_no_sql := IF( @idx_wh_stock_lot_item_lot_no_exists = 0, 'ALTER TABLE wh_stock_lot ADD INDEX idx_wh_stock_lot_item_lot_no (item_id, lot_no)', 'SELECT ''idx_wh_stock_lot_item_lot_no already exists''' ); PREPARE idx_wh_stock_lot_item_lot_no_stmt FROM @idx_wh_stock_lot_item_lot_no_sql; EXECUTE idx_wh_stock_lot_item_lot_no_stmt; DEALLOCATE PREPARE idx_wh_stock_lot_item_lot_no_stmt; SET @duplicate_stock_lot_no_groups := ( SELECT COUNT(*) FROM ( SELECT lot_no FROM wh_stock_lot WHERE lot_no IS NOT NULL GROUP BY lot_no HAVING COUNT(*) > 1 ) duplicated_lots ); SET @uq_wh_stock_lot_lot_no_sql := ( SELECT IF( @duplicate_stock_lot_no_groups > 0, CONCAT('SIGNAL SQLSTATE ''45000'' SET MESSAGE_TEXT = ''wh_stock_lot.lot_no存在重复,重复批次号组数=', @duplicate_stock_lot_no_groups, ',请先清理后再执行迁移'''), IF( NOT EXISTS ( SELECT 1 FROM ( SELECT INDEX_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'wh_stock_lot' GROUP BY INDEX_NAME HAVING MAX(NON_UNIQUE) = 0 AND COUNT(*) = 1 AND SUM(CASE WHEN COLUMN_NAME = 'lot_no' THEN 1 ELSE 0 END) = 1 ) existing_unique_lot_no_indexes ), 'ALTER TABLE wh_stock_lot ADD UNIQUE KEY uq_wh_stock_lot_lot_no (lot_no)', 'SELECT ''uq_wh_stock_lot_lot_no already exists''' ) ) ); PREPARE uq_wh_stock_lot_lot_no_stmt FROM @uq_wh_stock_lot_lot_no_sql; EXECUTE uq_wh_stock_lot_lot_no_stmt; DEALLOCATE PREPARE uq_wh_stock_lot_lot_no_stmt; SET @idx_pp_issue_source_lot_exists := ( SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pp_work_order_material_issue' AND COLUMN_NAME = 'source_lot_id' ); SET @idx_pp_issue_source_lot_sql := IF( @idx_pp_issue_source_lot_exists = 0, 'ALTER TABLE pp_work_order_material_issue ADD INDEX idx_pp_issue_source_lot (source_lot_id)', 'SELECT ''source_lot_id index already exists on pp_work_order_material_issue''' ); PREPARE idx_pp_issue_source_lot_stmt FROM @idx_pp_issue_source_lot_sql; EXECUTE idx_pp_issue_source_lot_stmt; DEALLOCATE PREPARE idx_pp_issue_source_lot_stmt; SET @uk_material_sub_batch_no_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pp_work_order_material_issue' AND INDEX_NAME = 'uk_material_sub_batch_no' ); SET @drop_uk_material_sub_batch_no_sql := IF( @uk_material_sub_batch_no_exists > 0, 'ALTER TABLE pp_work_order_material_issue DROP INDEX uk_material_sub_batch_no', 'SELECT ''uk_material_sub_batch_no already absent on pp_work_order_material_issue''' ); PREPARE drop_uk_material_sub_batch_no_stmt FROM @drop_uk_material_sub_batch_no_sql; EXECUTE drop_uk_material_sub_batch_no_stmt; DEALLOCATE PREPARE drop_uk_material_sub_batch_no_stmt; INSERT INTO po_purchase_order_sales_order (purchase_order_id, sales_order_id, created_at, updated_at) SELECT DISTINCT po.id, so.id, NOW(), NOW() FROM po_purchase_order po JOIN po_purchase_order_item poi ON poi.purchase_order_id = po.id JOIN mrp_material_demand md ON md.id = poi.source_demand_id JOIN so_sales_order_item soi ON soi.id = md.sales_order_item_id JOIN so_sales_order so ON so.id = soi.sales_order_id WHERE NOT EXISTS ( SELECT 1 FROM po_purchase_order_sales_order existing WHERE existing.purchase_order_id = po.id AND existing.sales_order_id = so.id ); UPDATE pp_work_order_material_issue issue JOIN wh_stock_lot lot ON lot.id = issue.source_lot_id SET issue.material_sub_batch_no = lot.lot_no WHERE issue.material_sub_batch_no IS NULL OR issue.material_sub_batch_no <> lot.lot_no;