-- ============================================================
|
-- 生产订单完整删除函数
|
-- 适用场景:待开始、进行中、已完成三种状态的生产订单删除
|
-- 生成日期:2026-06-11
|
-- ============================================================
|
|
DELIMITER $$
|
|
DROP FUNCTION IF EXISTS fn_delete_production_order$$
|
|
CREATE FUNCTION fn_delete_production_order(
|
p_order_id BIGINT,
|
p_force_delete TINYINT DEFAULT 0 -- 0=安全模式(已生产不允许删除), 1=强制删除
|
) RETURNS VARCHAR(500)
|
DETERMINISTIC
|
READS SQL DATA
|
BEGIN
|
DECLARE v_order_status INT DEFAULT 0;
|
DECLARE v_complete_quantity DECIMAL(20,4) DEFAULT 0;
|
DECLARE v_quantity DECIMAL(20,4) DEFAULT 0;
|
DECLARE v_nps_no VARCHAR(100) DEFAULT '';
|
DECLARE v_has_pick_record INT DEFAULT 0;
|
DECLARE v_has_product_main INT DEFAULT 0;
|
DECLARE v_has_quality_inspect INT DEFAULT 0;
|
DECLARE v_has_stock_record INT DEFAULT 0;
|
DECLARE v_deleted_count INT DEFAULT 0;
|
DECLARE v_result VARCHAR(500) DEFAULT '';
|
|
-- 查询订单基本信息
|
SELECT status, complete_quantity, quantity, nps_no
|
INTO v_order_status, v_complete_quantity, v_quantity, v_nps_no
|
FROM production_order
|
WHERE id = p_order_id;
|
|
-- 订单不存在
|
IF v_order_status IS NULL THEN
|
RETURN CONCAT('删除失败:生产订单不存在,ID=', p_order_id);
|
END IF;
|
|
-- 安全模式下检查是否允许删除
|
IF p_force_delete = 0 THEN
|
-- 状态检查:只有待开始(1)和已取消(4)允许删除
|
IF v_order_status = 2 THEN
|
RETURN CONCAT('删除失败:订单[', v_nps_no, ']正在进行中,不允许删除');
|
END IF;
|
|
IF v_order_status = 3 THEN
|
RETURN CONCAT('删除失败:订单[', v_nps_no, ']已完成,不允许删除');
|
END IF;
|
|
IF v_order_status = 5 THEN
|
RETURN CONCAT('删除失败:订单[', v_nps_no, ']已结束,不允许删除');
|
END IF;
|
END IF;
|
|
-- ========== 第一步:检查关联数据是否存在 ==========
|
|
-- 检查领料记录
|
SELECT COUNT(*) INTO v_has_pick_record
|
FROM production_order_pick_record
|
WHERE production_order_id = p_order_id;
|
|
-- 检查报工记录
|
SELECT COUNT(*) INTO v_has_product_main
|
FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id;
|
|
-- 检查质检记录
|
SELECT COUNT(*) INTO v_has_quality_inspect
|
FROM quality_inspect qi
|
INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id;
|
|
-- 检查库存记录(通过报工入库)
|
SELECT COUNT(*) INTO v_has_stock_record
|
FROM stock_in_record sir
|
INNER JOIN production_product_main ppm ON sir.record_id = ppm.id
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
AND sir.record_type IN ('2', '5'); -- 生产报工入库
|
|
-- ========== 第二步:删除关联数据(从叶子到根) ==========
|
|
-- 【第1层】删除质检附件
|
DELETE FROM quality_inspect_file
|
WHERE inspect_id IN (
|
SELECT qi.id FROM quality_inspect qi
|
INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第2层】删除质检参数
|
DELETE FROM quality_inspect_param
|
WHERE inspect_id IN (
|
SELECT qi.id FROM quality_inspect qi
|
INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第3层】删除不合格品记录
|
DELETE FROM quality_unqualified
|
WHERE inspect_id IN (
|
SELECT qi.id FROM quality_inspect qi
|
INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第4层】删除质检记录(过程检验、出厂检验)
|
DELETE FROM quality_inspect
|
WHERE product_main_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第5层】删除库存入库记录(生产报工入库、报废入库)
|
DELETE FROM stock_in_record
|
WHERE record_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
) AND record_type IN ('2', '5', '7'); -- 生产报工入库、报废入库
|
|
-- 删除质检入库记录
|
DELETE FROM stock_in_record
|
WHERE record_id IN (
|
SELECT qi.id FROM quality_inspect qi
|
INNER JOIN production_product_main ppm ON qi.product_main_id = ppm.id
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
) AND record_type = '6'; -- 质检入库
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第6层】删除库存出库记录(生产报工出库)
|
DELETE FROM stock_out_record
|
WHERE record_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
) AND record_type = '13'; -- 生产报工出库
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第7层】删除报工产出
|
DELETE FROM production_product_output
|
WHERE production_product_main_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第8层】删除报工投入
|
DELETE FROM production_product_input
|
WHERE production_product_main_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第9层】删除生产核算
|
DELETE FROM production_account
|
WHERE production_product_main_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第10层】删除报工工序参数(通过production_product_main_id关联)
|
DELETE FROM production_order_routing_operation_param
|
WHERE production_product_main_id IN (
|
SELECT ppm.id FROM production_product_main ppm
|
INNER JOIN production_operation_task pot ON ppm.production_operation_task_id = pot.id
|
WHERE pot.production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第11层】删除报工主表
|
DELETE FROM production_product_main
|
WHERE production_operation_task_id IN (
|
SELECT id FROM production_operation_task
|
WHERE production_order_id = p_order_id
|
);
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第12层】删除领料记录
|
DELETE FROM production_order_pick_record
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第13层】删除领料入库记录(退料)
|
DELETE FROM stock_in_record
|
WHERE record_id IN (
|
SELECT id FROM production_order_pick
|
WHERE production_order_id = p_order_id
|
) AND record_type IN ('20', '22'); -- 领料退料入库
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第14层】删除领料单
|
DELETE FROM production_order_pick
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第15层】删除生产工单
|
DELETE FROM production_operation_task
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第16层】删除工序参数(订单级别)
|
DELETE FROM production_order_routing_operation_param
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第17层】删除工序
|
DELETE FROM production_order_routing_operation
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第18层】删除工艺路线
|
DELETE FROM production_order_routing
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第19层】删除BOM结构
|
DELETE FROM production_bom_structure
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第20层】删除订单BOM
|
DELETE FROM production_order_bom
|
WHERE production_order_id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 【第21层】删除生产计划关联(回退计划已下发数量)
|
-- 注意:这里需要根据业务逻辑回退production_plan的quantity_issued和status
|
-- 由于production_plan_ids是JSON格式[1,2,3],需要特殊处理
|
-- 此处仅删除订单,计划回退逻辑建议在应用层处理
|
|
-- 【第22层】删除生产订单主表
|
DELETE FROM production_order
|
WHERE id = p_order_id;
|
SET v_deleted_count = v_deleted_count + ROW_COUNT();
|
|
-- 返回结果
|
SET v_result = CONCAT(
|
'删除成功:订单[', v_nps_no, '],',
|
'状态=', CASE v_order_status
|
WHEN 1 THEN '待开始'
|
WHEN 2 THEN '进行中'
|
WHEN 3 THEN '已完成'
|
WHEN 4 THEN '已取消'
|
WHEN 5 THEN '已结束'
|
ELSE '未知'
|
END, ',',
|
'共删除', v_deleted_count, '条关联数据'
|
);
|
|
RETURN v_result;
|
|
END$$
|
|
DELIMITER ;
|
|
-- ============================================================
|
-- 批量删除生产订单存储过程
|
-- ============================================================
|
|
DELIMITER $$
|
|
DROP PROCEDURE IF EXISTS sp_batch_delete_production_order$$
|
|
CREATE PROCEDURE sp_batch_delete_production_order(
|
IN p_order_ids TEXT, -- 订单ID列表,逗号分隔,如 "1,2,3"
|
IN p_force_delete TINYINT -- 0=安全模式, 1=强制删除
|
)
|
BEGIN
|
DECLARE v_order_id BIGINT;
|
DECLARE v_done INT DEFAULT FALSE;
|
DECLARE v_cursor CURSOR FOR
|
SELECT CAST(TRIM(value) AS UNSIGNED)
|
FROM JSON_TABLE(CONCAT('[', p_order_ids, ']'), '$[*]' COLUMNS(value VARCHAR(20) PATH '$')) AS jt;
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
|
|
DECLARE v_success_count INT DEFAULT 0;
|
DECLARE v_fail_count INT DEFAULT 0;
|
DECLARE v_result_msg VARCHAR(500);
|
|
-- 创建临时表记录结果
|
DROP TEMPORARY TABLE IF EXISTS tmp_delete_result;
|
CREATE TEMPORARY TABLE tmp_delete_result (
|
order_id BIGINT,
|
result VARCHAR(500)
|
);
|
|
OPEN v_cursor;
|
|
read_loop: LOOP
|
FETCH v_cursor INTO v_order_id;
|
IF v_done THEN
|
LEAVE read_loop;
|
END IF;
|
|
-- 调用删除函数
|
SET v_result_msg = fn_delete_production_order(v_order_id, p_force_delete);
|
|
-- 记录结果
|
INSERT INTO tmp_delete_result (order_id, result) VALUES (v_order_id, v_result_msg);
|
|
-- 统计
|
IF v_result_msg LIKE '删除成功%' THEN
|
SET v_success_count = v_success_count + 1;
|
ELSE
|
SET v_fail_count = v_fail_count + 1;
|
END IF;
|
|
END LOOP;
|
|
CLOSE v_cursor;
|
|
-- 输出结果
|
SELECT
|
CONCAT('批量删除完成:成功', v_success_count, '个,失败', v_fail_count, '个') AS summary;
|
|
SELECT * FROM tmp_delete_result;
|
|
DROP TEMPORARY TABLE IF EXISTS tmp_delete_result;
|
|
END$$
|
|
DELIMITER ;
|
|
-- ============================================================
|
-- 使用示例
|
-- ============================================================
|
|
-- 示例1:安全模式删除单个订单(只能删除待开始/已取消状态)
|
-- SELECT fn_delete_production_order(123, 0);
|
|
-- 示例2:强制删除单个订单(忽略状态检查)
|
-- SELECT fn_delete_production_order(123, 1);
|
|
-- 示例3:批量删除订单
|
-- CALL sp_batch_delete_production_order('123,124,125', 0);
|
|
-- 示例4:批量强制删除
|
-- CALL sp_batch_delete_production_order('123,124,125', 1);
|