Pernahkah Anda ingin database otomatis mencatat perubahan data, memvalidasi input, atau memperbarui tabel lain setiap kali ada operasi INSERT, UPDATE, atau DELETE? Itulah fungsi Trigger di MySQL. Trigger adalah prosedur yang dieksekusi secara otomatis oleh MySQL sebagai respons terhadap event tertentu pada sebuah tabel. Artikel ini membahas cara membuat trigger MySQL secara lengkap dengan contoh nyata.
Konsep Dasar Trigger
Sebuah trigger memiliki tiga komponen utama:
- Event: Kapan trigger aktif โ
INSERT,UPDATE, atauDELETE. - Timing: Apakah trigger berjalan
BEFORE(sebelum) atauAFTER(setelah) event terjadi. - Body: Logika SQL yang dieksekusi ketika trigger aktif.
Di dalam body trigger, Anda bisa mengakses dua referensi khusus: NEW (nilai baru yang akan/sudah disimpan) dan OLD (nilai lama sebelum diubah/dihapus).
Persiapan Tabel Contoh
-- Tabel produk utama
CREATE TABLE produk (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(200) NOT NULL,
harga DECIMAL(10,2) NOT NULL,
stok INT NOT NULL DEFAULT 0,
diperbarui DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- Tabel log untuk mencatat perubahan harga
CREATE TABLE log_perubahan_harga (
id INT AUTO_INCREMENT PRIMARY KEY,
id_produk INT NOT NULL,
harga_lama DECIMAL(10,2) NOT NULL,
harga_baru DECIMAL(10,2) NOT NULL,
diubah_pada DATETIME DEFAULT CURRENT_TIMESTAMP,
diubah_oleh VARCHAR(100) DEFAULT USER()
) ENGINE=InnoDB;
-- Tabel log untuk stok
CREATE TABLE log_stok (
id INT AUTO_INCREMENT PRIMARY KEY,
id_produk INT NOT NULL,
aksi ENUM('MASUK', 'KELUAR', 'HAPUS') NOT NULL,
stok_sebelum INT NOT NULL,
stok_sesudah INT NOT NULL,
selisih INT NOT NULL,
dicatat DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
Trigger AFTER UPDATE โ Mencatat Perubahan Harga
Trigger ini otomatis mencatat setiap perubahan harga ke tabel log:
DELIMITER $$
CREATE TRIGGER trg_log_perubahan_harga
AFTER UPDATE ON produk
FOR EACH ROW
BEGIN
-- Hanya catat jika harga benar-benar berubah
IF OLD.harga <> NEW.harga THEN
INSERT INTO log_perubahan_harga
(id_produk, harga_lama, harga_baru)
VALUES
(NEW.id, OLD.harga, NEW.harga);
END IF;
END$$
DELIMITER ;
-- Test trigger
INSERT INTO produk (nama, harga, stok) VALUES ('Laptop ASUS', 8500000, 10);
UPDATE produk SET harga = 9000000 WHERE id = 1;
-- Cek log
SELECT * FROM log_perubahan_harga;
Trigger AFTER UPDATE โ Mencatat Perubahan Stok
DELIMITER $$
CREATE TRIGGER trg_log_stok
AFTER UPDATE ON produk
FOR EACH ROW
BEGIN
DECLARE v_aksi ENUM('MASUK', 'KELUAR', 'HAPUS');
DECLARE v_selisih INT;
SET v_selisih = NEW.stok - OLD.stok;
IF v_selisih > 0 THEN
SET v_aksi = 'MASUK';
ELSEIF v_selisih < 0 THEN
SET v_aksi = 'KELUAR';
ELSE
LEAVE; -- tidak ada perubahan stok
END IF;
INSERT INTO log_stok
(id_produk, aksi, stok_sebelum, stok_sesudah, selisih)
VALUES
(NEW.id, v_aksi, OLD.stok, NEW.stok, ABS(v_selisih));
END$$
DELIMITER ;
Trigger BEFORE INSERT โ Validasi Data
BEFORE trigger berguna untuk memvalidasi atau memodifikasi data sebelum disimpan:
DELIMITER $$
CREATE TRIGGER trg_validasi_harga
BEFORE INSERT ON produk
FOR EACH ROW
BEGIN
-- Pastikan harga tidak negatif
IF NEW.harga <= 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Harga produk harus lebih besar dari 0';
END IF;
-- Pastikan stok tidak negatif
IF NEW.stok < 0 THEN
SET NEW.stok = 0; -- otomatis set ke 0 jika negatif
END IF;
-- Kapitalisasi nama produk
SET NEW.nama = UPPER(LEFT(NEW.nama, 1))
|| LOWER(SUBSTRING(NEW.nama, 2));
END$$
DELIMITER ;
-- Test: ini akan GAGAL karena harga negatif
-- INSERT INTO produk (nama, harga, stok) VALUES ('Test', -100, 5);
-- Test: stok negatif akan otomatis jadi 0
INSERT INTO produk (nama, harga, stok) VALUES ('Mouse Wireless', 350000, -5);
SELECT stok FROM produk WHERE nama = 'Mouse Wireless';
Trigger AFTER DELETE โ Arsip Data yang Dihapus
-- Buat tabel arsip
CREATE TABLE arsip_produk (
id INT NOT NULL,
nama VARCHAR(200),
harga DECIMAL(10,2),
stok INT,
dihapus_pada DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
DELIMITER $$
CREATE TRIGGER trg_arsip_produk
AFTER DELETE ON produk
FOR EACH ROW
BEGIN
INSERT INTO arsip_produk (id, nama, harga, stok)
VALUES (OLD.id, OLD.nama, OLD.harga, OLD.stok);
-- Catat di log stok juga
INSERT INTO log_stok
(id_produk, aksi, stok_sebelum, stok_sesudah, selisih)
VALUES
(OLD.id, 'HAPUS', OLD.stok, 0, OLD.stok);
END$$
DELIMITER ;
Melihat dan Menghapus Trigger
-- Lihat semua trigger di database aktif
SHOW TRIGGERS;
-- Lihat trigger pada tabel tertentu
SHOW TRIGGERS FROM nama_database LIKE 'produk';
-- Lihat detail trigger dari INFORMATION_SCHEMA
SELECT
TRIGGER_NAME,
EVENT_MANIPULATION,
ACTION_TIMING,
EVENT_OBJECT_TABLE
FROM INFORMATION_SCHEMA.TRIGGERS
WHERE TRIGGER_SCHEMA = DATABASE()
ORDER BY EVENT_OBJECT_TABLE, ACTION_TIMING;
-- Hapus trigger
DROP TRIGGER IF EXISTS trg_log_perubahan_harga;
Hal yang Perlu Diperhatikan
- Satu tabel bisa memiliki maksimum 6 trigger (BEFORE/AFTER ร INSERT/UPDATE/DELETE).
- Trigger tidak bisa memanggil dirinya sendiri secara rekursif secara default.
- Hindari logika yang terlalu berat di dalam trigger karena akan memperlambat operasi DML.
- Gunakan
SIGNAL SQLSTATEuntuk membatalkan operasi dan menampilkan pesan error. - Referensi
OLDtersedia untuk UPDATE dan DELETE, sedangkanNEWuntuk INSERT dan UPDATE.
Kesimpulan
Trigger MySQL adalah alat yang powerful untuk mengotomatiskan aksi database sebagai respons terhadap event INSERT, UPDATE, atau DELETE. Dengan trigger, Anda bisa membuat sistem audit log otomatis, memvalidasi data sebelum disimpan, atau menjaga konsistensi data antar tabel tanpa perlu menulis logika tambahan di aplikasi. Gunakan BEFORE trigger untuk validasi dan modifikasi data, serta AFTER trigger untuk pencatatan dan sinkronisasi data ke tabel lain.