更新后在触发器中更新同一个表

问题描述 投票:0回答:1

如何更新同一张表?它抛出错误“无法更新存储函数/触发器中的表'admission',因为它已被调用此存储函数/触发器的语句使用。”


DELIMITER $$

CREATE
    TRIGGER `final_admitted` AFTER UPDATE ON `admission` 
    FOR EACH ROW BEGIN

    IF NEW.`latest_record` <> OLD.`latest_record` OR
    NEW.`is_canceled` <> OLD.`is_canceled` OR
    NEW.`admission_payment` <> OLD.`admission_payment` OR
    NEW.`is_verified` <> OLD.`is_verified` OR
    NEW.`course_payment` <> OLD.`course_payment`
      THEN
        
        UPDATE `admission` SET `final_admitted`='0' WHERE `id`=NEW.id;
              
        UPDATE`admission` AS A 
    JOIN `course_live_details` AS CS ON A.`course_id`=A.`course_id` AND A.`app_id`=CS.app_id
    SET final_admitted='1'
    WHERE A.`id`= NEW.id AND 
    A.`latest_record`='1' AND 
    A.`is_canceled`='0' AND
    ((CS.remaining_course_fee_required='1' AND A.`course_payment`='2') OR (CS.remaining_course_fee_required='0' AND A.`course_payment`!='99')) AND
    ((CS.`final_admitted_type`='P' AND A.`admission_payment`='2') OR
    (CS.`final_admitted_type`='V' AND A.`is_verified`='1') OR (CS.`final_admitted_type`='PV' AND A.`admission_payment`='2' AND A.`is_verified`='1'));
        
    END IF;
END;
$$

我试过这个-

UPDATE 
录取
SET
最终录取
='0' WHERE 
id`=NEW.id;

    UPDATE`admission` AS A 
JOIN `course_live_details` AS CS ON A.`course_id`=A.`course_id` AND A.`app_id`=CS.app_id
SET final_admitted='1'
WHERE A.`id`= NEW.id AND 
A.`latest_record`='1' AND 
A.`is_canceled`='0' AND
((CS.remaining_course_fee_required='1' AND A.`course_payment`='2') OR (CS.remaining_course_fee_required='0' AND A.`course_payment`!='99')) AND
((CS.`final_admitted_type`='P' AND A.`admission_payment`='2') OR
(CS.`final_admitted_type`='V' AND A.`is_verified`='1') OR (CS.`final_admitted_type`='PV' AND A.`admission_payment`='2' AND A.`is_verified`='1'));`
sql mysql triggers
1个回答
0
投票

您遇到的错误是由于您尝试更新触发存储的函数/触发器的同一个表(准入)。这在 SQL 中是不允许的,因为它可能导致无限循环和其他问题。

要解决此问题,您可以通过创建临时表来存储需要更新的 ID,然后根据该临时表更新准入表来解决此问题。

DELIMITER $$

CREATE
    TRIGGER `final_admitted` AFTER UPDATE ON `admission` 
    FOR EACH ROW BEGIN

    IF NEW.`latest_record` <> OLD.`latest_record` OR
    NEW.`is_canceled` <> OLD.`is_canceled` OR
    NEW.`admission_payment` <> OLD.`admission_payment` OR
    NEW.`is_verified` <> OLD.`is_verified` OR
    NEW.`course_payment` <> OLD.`course_payment`
      THEN
        
        -- Create a temporary table to store the IDs that need to be updated
        CREATE TEMPORARY TABLE temp_ids (
            id INT
        );
        
        -- Insert the ID into the temporary table
        INSERT INTO temp_ids (id) VALUES (NEW.id);
        
        -- Update the admission table based on the temporary table
        UPDATE `admission` AS A 
        JOIN temp_ids AS T ON A.`id` = T.`id`
        SET `final_admitted` = '0';
        
        UPDATE `admission` AS A 
        JOIN `course_live_details` AS CS ON A.`course_id` = A.`course_id` AND A.`app_id` = CS.app_id
        JOIN temp_ids AS T ON A.`id` = T.`id`
        SET `final_admitted` = '1'
        WHERE A.`latest_record` = '1' AND 
        A.`is_canceled` = '0' AND
        ((CS.remaining_course_fee_required = '1' AND A.`course_payment` = '2') OR 
         (CS.remaining_course_fee_required = '0' AND A.`course_payment` != '99')) AND
        ((CS.`final_admitted_type` = 'P' AND A.`admission_payment` = '2') OR 
         (CS.`final_admitted_type` = 'V' AND A.`is_verified` = '1') OR 
         (CS.`final_admitted_type` = 'PV' AND A.`admission_payment` = '2' AND A.`is_verified` = '1'));
        
        -- Drop the temporary table
        DROP TABLE temp_ids;
    END IF;
END;
$$
© www.soinside.com 2019 - 2024. All rights reserved.