我有2个MySQL触发器,“before update”和“after update”在同一个表上,当调用时,我得到一个错误:错误代码:1442

lstz6jyr  于 2023-03-17  发布在  Mysql
关注(0)|答案(1)|浏览(198)

表中包含员工工作详细信息,如公司名称、开始日期、所得税等级、结束日期、工资等。每个员工可以同时在多个公司工作,其中一个公司的“所得税等级”必须为“类别01”,其余公司的“所得税等级”必须为“类别05”。
我尝试在MySQL中添加2个触发器,一个是“更新前”,另一个是“更新后”在同一个表上。“更新前”触发器是在我尝试将结束日期添加到公司时调用的,然后触发器将列“working_status”设置为“inactive”。第二个触发器“更新后”应该在更新公司的结束日期后调用,然后,它应该检查是否存在具有“活动”“工作状态”和“类别01”所得税的行,如果不存在这样的行,则它应该基于最早开始日期将现有“活动”行的所得税等级之一更新为“类别01”。
尝试时,我收到以下错误:错误代码:1442.无法更新存储函数/触发器中的表'companydetails',因为调用此存储函数/触发器的语句已经使用了它。
触发器1:

`DROP TRIGGER IF EXISTS workingStatusUpdate;
DELIMITER //
CREATE TRIGGER workingStatusUpdate
BEFORE UPDATE ON companyDetails FOR EACH ROW
workingStUpdate: BEGIN
    DECLARE Tri_userID INT(10);
    DECLARE Tri_endDate DATE;
    DECLARE Tri_companyName VARCHAR(60);    
    DECLARE endCount INT(10);
    SET Tri_userID = new.user_id;
    SET Tri_endDate = new.end_date;
    SET Tri_companyName = new.company_name;
    SELECT count(*) INTO endCount FROM companyDetails WHERE user_id = Tri_userID 
    and company_name = Tri_companyName and Tri_endDate IS NOT NULL;
    IF endCount > 0 THEN
    SET new.working_status = 'Inactive';
    END IF;
END //
DELIMITER ;
`

触发器2:

`DROP TRIGGER IF EXISTS atleastOneCat01Row;
DELIMITER //
CREATE TRIGGER atleastOneCat01Row
AFTER UPDATE on companyDetails FOR EACH ROW
incomeTaxBracketUpdate: BEGIN
    DECLARE Tri_userID INT(10);
    DECLARE Tri_endDate DATE;
    DECLARE catOneRowCount INT(5);
    SET Tri_userID = new.user_id;
    SET Tri_endDate = new.end_date;
    SELECT COUNT(*) INTO catOneRowCount FROM companyDetails WHERE user_id = Tri_userID 
    and working_status = 'Active' and income_tax_bracket = 'Cat01';
    IF catOneRowCount = 0 THEN
    UPDATE companyDetails SET income_tax_bracket = 'Cat01' WHERE user_id = Tri_userID 
        and working_status = 'Active' ORDER BY start_date limit 1;
    END IF;
END //
DELIMITER ;`

我尝试更改为更新前,但它没有给予出我所期望的输出。

pobjuy32

pobjuy321#

如果更新表中启动触发器的行,则不能在触发器中修改该表中的其他行:
存储函数或触发器不能修改已由调用该函数或触发器的语句使用(用于阅读或写入)的表。
表中唯一可以修改的行是刚刚更新的行,这是MySQL无法做到的。
您可以尝试以下方法:

  • 您在应用程序中进行额外的更新,例如,每当应用程序更改表时,它也将运行tax-bracket-correction-query(基本上您运行自己的触发器)。
  • 如果你的用户直接在数据库上工作(例如运行他们自己的查询),你只能通过存储过程对该表进行更改,例如你可以有一个存储过程setCompDetEndDate,它设置结束日期,然后还运行你的附加查询。2你可能希望撤销在没有该过程的情况下修改该表的权限。
  • 你可以修改你的数据结构并以不同的方式存储信息。例如,你可以向employee-table添加一列Cat01Company,并在你的触发器中更新该列(你可以修改其他表,但不能修改companyDetails)。如果你想知道company details中的一行是cat 01还是cat 05,你可以检查employee表。
  • 您根本不存储这些信息,但是如果您想知道税码,您可以检查是否存在同一员工的早期活动行。

注意,您的triggercode当前不检查是否有2行带有“Cat 01”(只有在没有的情况下),因此如果您选择前两个选项中的一个,您可能也需要添加一个检查。

相关问题