如何在MySQL Trigger(触发器)中使用Cursor(游标)实现多表数据联动
Mst_Sales表更新同步触发器(游标实现方案)
前置假设
为避免歧义,先约定通用关联逻辑,你可以根据自己的实际表结构替换对应字段:
- Mst_Sales(主表)与Txn_Sales(事务表)通过公共字段
SalesID关联 - txn_dbtransactionnotification(通知表)参考结构:
NotificationID自增主键SalesID关联主表IDTxnID关联事务表行IDChangeType操作类型,固定为UPDATEChangeTime变更时间,默认当前时间OldValue变更前字段值NewValue变更后字段值
完整实现代码(SQL Server 环境)
CREATE TRIGGER trg_MstSales_Update ON Mst_Sales AFTER UPDATE AS BEGIN SET NOCOUNT ON; -- 声明变量存储主表变更前后的值 DECLARE @SalesID INT, @NewCustomerName VARCHAR(100), @OldCustomerName VARCHAR(100), @NewOrderAmount DECIMAL(18,2), @OldOrderAmount DECIMAL(18,2) -- 声明变量存储事务表ID,用于插入通知表 DECLARE @TxnID INT -- 外层游标:遍历所有被更新的主表行(兼容批量更新主表的场景) DECLARE mst_cursor CURSOR FOR SELECT i.SalesID, i.CustomerName, d.CustomerName, i.OrderAmount, d.OrderAmount FROM inserted i INNER JOIN deleted d ON i.SalesID = d.SalesID OPEN mst_cursor FETCH NEXT FROM mst_cursor INTO @SalesID, @NewCustomerName, @OldCustomerName, @NewOrderAmount, @OldOrderAmount WHILE @@FETCH_STATUS = 0 BEGIN -- 内层游标:逐行更新对应事务表的关联数据 DECLARE txn_cursor CURSOR FOR SELECT TxnID FROM Txn_Sales WHERE SalesID = @SalesID OPEN txn_cursor FETCH NEXT FROM txn_cursor INTO @TxnID WHILE @@FETCH_STATUS = 0 BEGIN -- 逐行更新事务表字段 UPDATE Txn_Sales SET CustomerName = @NewCustomerName, OrderAmount = @NewOrderAmount WHERE TxnID = @TxnID -- 插入变更通知记录 INSERT INTO txn_dbtransactionnotification (SalesID, TxnID, ChangeType, OldValue, NewValue, ChangeTime) VALUES (@SalesID, @TxnID, 'UPDATE', CONCAT('CustomerName:', @OldCustomerName, ', OrderAmount:', @OldOrderAmount), CONCAT('CustomerName:', @NewCustomerName, ', OrderAmount:', @NewOrderAmount), GETDATE()) FETCH NEXT FROM txn_cursor INTO @TxnID END -- 释放内层游标资源 CLOSE txn_cursor DEALLOCATE txn_cursor FETCH NEXT FROM mst_cursor INTO @SalesID, @NewCustomerName, @OldCustomerName, @NewOrderAmount, @OldOrderAmount END -- 释放外层游标资源 CLOSE mst_cursor DEALLOCATE mst_cursor END GO
注意事项
- 代码中同步的字段(CustomerName、OrderAmount)仅为示例,替换为你实际需要同步的字段即可
- 支持Mst_Sales批量更新的场景,不会出现只更新第一条的问题
- 游标使用完必须关闭和释放,避免占用数据库资源
- 如果没有强制要求使用游标,更推荐用集合操作实现,性能会高很多,仅需把内层游标替换为
UPDATE Txn_Sales ... FROM inserted+批量插入通知表的语句即可
内容的提问来源于stack exchange,提问作者Yogesh Shinde
相关产品推荐
相关产品推荐

