首页 >数据库 >mysql教程 >如何使用存储过程更新 MySQL 表中的前一行和新行?

如何使用存储过程更新 MySQL 表中的前一行和新行?

Susan Sarandon
Susan Sarandon原创
2024-10-29 13:51:29324浏览

How to Update Previous and New Rows in a MySQL Table Using Stored Procedures?

使用触发器修改 MySQL 表中的上一行和新行

问题:

在表中跟踪项目费用,您想要插入新的费用记录,同时使用相同的 procKey 更新先前记录的 endDate 以在新记录的 startDate 前一天结束。

初始方法:

您尝试使用以下代码创建触发器:

CREATE
DEFINER=`root`@`%`
TRIGGER `im`.`splitBeforeIns`
BEFORE INSERT ON `im`.`split`
FOR EACH ROW
BEGIN
    SET NEW.tcPercent = (NEW.tcOfficeFee / NEW.globalFee) * 100 , NEW.proPercent = 100 - NEW.tcPercent, NEW.endDate = 20501231;
    UPDATE im.split set endDate = ADDDATE(NEW.startDate, -1) where procKey = NEW.procKey AND endDate = 20501231;
END$$

但是,此触发器导致错误:“无法更新存储函数/触发器中的表‘split’,因为它已经是由调用此存储函数/触发器的语句使用。”

解决方案:

触发器不能修改同一表中的其他行。

要实现所需的功能,必须使用存储过程而不是触发器。存储过程可以作为单个事务的一部分执行多个操作,包括插入或更新您要修改的表。

示例存储过程:

CREATE PROCEDURE updateSplit(IN @procKey INT, IN @startDate DATE, IN @endDate DATE)
BEGIN
    DECLARE @errorMessage VARCHAR(255);
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    START TRANSACTION;
    INSERT INTO split (procKey, startDate, endDate, tcOfficeFee, globalFee) 
    VALUES (@procKey, @startDate, @endDate, @tcOfficeFee, @globalFee);
    
    IF @@ROWCOUNT > 0 THEN
        -- Only update previous record if a new row was successfully inserted
        UPDATE split SET endDate = ADDDATE(@startDate, -1)
        WHERE procKey = @procKey AND endDate = 20501231;
        
        IF @@ROWCOUNT > 0 THEN
            COMMIT;
        ELSE
            SET @errorMessage = 'Failed to update previous record';
            ROLLBACK;
        END IF;
    ELSE
        SET @errorMessage = 'Failed to insert new record';
        ROLLBACK;
    END IF;
END

此存储过程可用于根据需要更新拆分表:

CALL updateSplit(123, '2022-06-01', '2022-06-30');

以上是如何使用存储过程更新 MySQL 表中的前一行和新行?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn