問題:
テーブル内のアイテムの追跡手数料新しい料金レコードを挿入すると同時に、同じ procKey を使用して以前のレコードの endDate を更新して、新しいレコードの startDate の 1 日前に終了するようにしたいとします。
初期アプローチ:
次のコードでトリガーを作成しようとしました:
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 中国語 Web サイトの他の関連記事を参照してください。