Masalah:
Dalam jadual bayaran penjejakan untuk item , anda ingin memasukkan rekod yuran baharu sambil mengemas kini secara serentak tarikh tamat rekod sebelumnya dengan procKey yang sama untuk tamat sehari sebelum tarikh mula rekod baharu.
Pendekatan Awal:
Anda cuba mencipta pencetus dengan kod berikut:
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$$
Walau bagaimanapun, pencetus ini mengakibatkan ralat: "Tidak dapat mengemas kini jadual 'berpecah' dalam fungsi/pencetus yang disimpan kerana ia sudah pun digunakan oleh pernyataan yang menggunakan fungsi/pencetus tersimpan ini."
Penyelesaian:
Pencetus tidak boleh mengubah suai baris lain dalam jadual yang sama.
Untuk mencapai kefungsian yang diingini, anda mesti menggunakan prosedur tersimpan dan bukannya pencetus. Prosedur tersimpan boleh melakukan berbilang operasi sebagai sebahagian daripada satu transaksi, termasuk memasukkan ke dalam atau mengemas kini jadual yang ingin anda ubah suai.
Contoh Prosedur Tersimpan:
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
Prosedur tersimpan ini boleh digunakan untuk mengemas kini jadual belah seperti yang dikehendaki:
CALL updateSplit(123, '2022-06-01', '2022-06-30');
Atas ialah kandungan terperinci Bagaimana untuk Mengemas kini Baris Sebelumnya dan Baharu dalam Jadual MySQL Menggunakan Prosedur Tersimpan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!