You are on page 1of 6

1

BAB VI
TRIGGER
6.1 DEFINISI TRIGGER
Trigger adalah sebuah objek database yang diasosiasikan dengan sebuah tabel dan
akan aktif (terpicu/trigger) ketika sebuah event terjadi pada tabel tersebut
Trigger hanya terjadi ketika ada eksekusi INSERT, DELETE dan UPDATE pada tabel
yang bersangkutan.
Waktu eksekusi trigger yang mungkin terjadi terdiri dari 2 yaitu BEFORE dan AFTER
dari statement SQL-nya
6.2 KEUNTUNGAN MENGGUNAKAN TRIGGER
Trigger dapat digunakan untuk mengubah data sebelum proses INSERT dilakukan atau
untuk memberikan nilai default. Misal mengubah data yang diluar nilai yang
diperbolehkan. Misalnya, jika ada pengisian nilai diatas 100, maka akan dijadikan 100.
Anda dapat menyimpan data suatu record ke tabel lain (misalnya history) sebelum data
tersebut diupdate atau didelete. Sehingga semua perubahan data dapat terlacak dari
sejak data itu dibuat.
6. 3 STRUKTUR TRIGGER
CREATE TRINGGER nama_trigger
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON nama_tabel
FOR EACH ROW
Statement-statement
6.4 MENGAKSES NILAI BARU DAN LAMA

Didalam trigger, anda dapat mengakses data lama dan baru. Data lama dapat
direference dengan record OLD dan data baru dapat dideference dengan record NEW.
OPERASI

NEW
(READ/WRITE)

OLD
(READ)

INSERT
UPDATE

DELETE

Untuk mengacu ke sebuah field dapat ditulis dengan NEW.namafield atau


OLD.namafield.

CONTOH 1
Ada sebuah database dbAkdemik yang mempunyai tabel mahasiswa {nim, nama,
alamat}.
Buatlah sebuah trigger yang akan menyimpan history alamat. Jika sebuah alamat
berubah, maka alamat lama harus disimpan ke tabel history_alamat_mhs.
JAWAB :
Persiapan awal
mysql>
mysql>
mysql>
->
->
->
mysql>
->
->
->
mysql>
->
->
->
->

CREATE DATABASE dbAkademik;


USE dbAkademik;
CREATE TABLE mhs(
Nim VARCHAR(10) PRIMARY KEY,
Nama VARCHAR(50) Not Null,
Alamat VARCHAR(200) Not Null);
INSERT INTO mhs values
('09.53.0042','Septario Sagita','Jl. aa No.1'),
('09.53.0045','Tanto Taufik N','Jl. bb No.2'),
('09.53.0062','Irfan Fajarudy','Jl. cc No.3');
CREATE TABLE history_alamat_mhs(
Waktu datetime,
Nim VARCHAR(8),
Alamat VARCHAR(200),
Oleh VARCHAR(50));

Pembuatan trigger
mysql> DELIMITER //
mysql> DROP TRIGGER IF EXISTS trig_update_mhs //
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> CREATE TRIGGER trig_update_mhs
-> AFTER UPDATE ON mhs
-> FOR EACH ROW
-> BEGIN
->
INSERT INTO history_alamat_mhs
->
VALUES (now(), OLD.nim, OLD.alamat, USER());
-> END//
Query OK, 0 rows affected (0.09 sec)
mysql> DELIMITER ;

Contoh penggunaan trigger


mysql> UPDATE mhs SET alamat='Ds. Lembah Jetis Rt 32/11 Madiun'
->
WHERE nim='09.53.0042';
mysql> UPDATE mhs SET alamat='Jl. Setiyasa 12 Madiun'
->
WHERE nim='09.53.0045';
mysql> UPDATE mhs SET alamat='Jl. Ronggo Pustoko Rt 06 Rw 03 Madiun'
->
WHERE nim='09.53.0062';
mysql> select * from mhs;
+------------+-----------------+---------------------------------------+
| Nim
| Nama
| Alamat
|
+------------+-----------------+---------------------------------------+
| 09.53.0042 | Septario Sagita | Ds. Lembah Jetis Rt 32/11 Madiun
|
| 09.53.0045 | Tanto taufik N | Jl. Setiyasa 12 Madiun
|
| 09.53.0062 | Irfan Fajarufy | Jl. Ronggo Pustoko Rt 06 Rw 03 Madiun |
+------------+-----------------+---------------------------------------+
mysql> select * from history_alamat_mhs;
+---------------------+------------+-------------+----------------+
| Waktu
| Nim
| Alamat
| Oleh
|
+---------------------+------------+-------------+----------------+
| 2010-10-19 03:41:43 | 09.53.0042 | Jl. aa No.1 | root@localhost |
| 2010-10-19 03:42:32 | 09.53.0045 | Jl. bb No.2 | root@localhost |
| 2010-10-19 03:43:13 | 09.53.0062 | Jl. cc No.3 | root@localhost |
+---------------------+------------+-------------+----------------+

Untuk melihat semua alamat yang pernah digunakan mhs yang bernim 09.53.0042
adalah :
mysql> (SELECT now() waktu, alamat FROM mhs WHERE nim='09.53.0042')
-> UNION
-> (SELECT waktu,alamat FROM history_alamat_mhs WHERE nim='09.53.0042')
-> ORDER BY waktu DESC;
+---------------------+----------------------------------+
| waktu
| alamat
|
+---------------------+----------------------------------+
| 2010-10-19 04:00:05 | Ds. Lembah Jetis Rt 32/11 Madiun |
| 2010-10-19 03:41:43 | Jl. aa No.1
|
+---------------------+----------------------------------+

Trigger pertama mempunyai kekurangan yaitu ketika ada perubahan di tabel mhs
walaupun tidak mengubah kolom alamat, maka statement INSERT di tabel history akan
dijalankan. Trigger ini bisa dioptimalkan dengan membuat trigger seperti dibawah ini :
mysql> DELIMITER //
mysql> DROP TRIGGER IF EXISTS trig_update_mhs //
mysql> CREATE TRIGGER trig_update_mhs
-> AFTER UPDATE ON mhs
-> FOR EACH ROW
-> BEGIN
->
IF OLD.alamat <> NEW.alamat THEN
->
INSERT INTO history_alamat_mhs
->
VALUES(now(),OLD.nim,OLD.alamat,USER());
->
END IF;
-> END //
Query OK, 0 rows affected (0.03 sec)
mysql> DELIMITER ;

3
CONTOH 2
Membuat sebuah trigger yang akan dieksekusi ketika ada perubahan NIM di tabel mhs
yang akan melakukan update ke tabel history_alamat_mhs untuk menyesuaikan NIM-nya
agar relasinya tidak terlepas.
mysql> DELIMITER //
mysql> DROP TRIGGER IF EXISTS trig_update_nim //
mysql> CREATE TRIGGER trig_update_nim
-> AFTER UPDATE ON mhs
-> FOR EACH ROW
-> BEGIN
->
IF OLD.nim <> NEW.nim THEN
->
UPDATE history_alamat_mhs SET nim=NEW.nim WHERE nim=OLD.nim;
->
END IF;
-> END//
ERROR 1235 (42000): This version of MySQL doesn't yet support 'multiple
triggers with the same action time and event for one table'

Jika trigger tersebut dieksekusi maka akan terlihat ada peringatan berisi : This version of
MySQL doesn't yet support 'multiple triggers with the same action time and event for one
table yang artinya anda tidak bisa membuat trigger pada sebuah tabel pada waktu dan event
yang sama.
Solusi yang bisa dilakukan adalah menggabung isi trigger trig_update_mhs dengan isi trigger
yang baru
mysql> DELIMITER //
mysql> DROP TRIGGER IF EXISTS trig_update_mhs //
mysql> CREATE TRIGGER trig_update_mhs
-> AFTER UPDATE ON mhs
-> FOR EACH ROW
-> BEGIN
->
IF OLD.alamat <> NEW.alamat THEN
->
INSERT INTO history_alamat_mhs
->
VALUES(now(),OLD.nim,OLD.alamat,USER());
->
END IF;
->
IF OLD.nim <> NEW.nim THEN
->
UPDATE history_alamat_mhs SET nim=NEW.nim WHERE nim=OLD.nim;
->
END IF;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;

Pengunaan trigger trig_update_mhs yang baru :

mysql> SELECT * FROM history_alamat_mhs;


+---------------------+------------+------------------------+----------------+
| Waktu
| Nim
| Alamat
| Oleh
|
+---------------------+------------+------------------------+----------------+
| 2010-10-19 03:41:43 | 09.53.0042 | Jl. aa No.1
| root@localhost |
| 2010-10-19 03:42:32 | 09.53.0045 | Jl. bb No.2
| root@localhost |
| 2010-10-19 03:43:13 | 09.53.0062 | Jl. cc No.3
| root@localhost |
| 2010-10-19 03:50:41 | 09.53.0045 | Jl. Setiyasa 12 Madiun | root@localhost |
+---------------------+------------+------------------------+----------------+
mysql> UPDATE mhs SET nim='09.53.1045' WHERE nim='09.53.0045';
mysql> SELECT * FROM history_alamat_mhs;
+---------------------+------------+------------------------+----------------+
| Waktu
| Nim
| Alamat
| Oleh
|
+---------------------+------------+------------------------+----------------+
| 2010-10-19 03:41:43 | 09.53.0042 | Jl. aa No.1
| root@localhost |
| 2010-10-19 03:42:32 | 09.53.1045 | Jl. bb No.2
| root@localhost |
| 2010-10-19 03:43:13 | 09.53.0062 | Jl. cc No.3
| root@localhost |
| 2010-10-19 03:50:41 | 09.53.1045 | Jl. Setiyasa 12 Madiun | root@localhost |
+---------------------+------------+------------------------+----------------+
4 rows in set (0.00 sec)

CONTOH 3
Membuat sebuah trigger yang akan menghapus semua data pada tabel history_alamat_mhs
ketika ada penghapusan pada tabel mhs.
mysql> DELIMITER //
mysql> DROP TRIGGER IF EXISTS trig_delete_mhs //

mysql> CREATE TRIGGER trig_delete_mhs


-> AFTER DELETE ON mhs
-> FOR EACH ROW
-> BEGIN
->
DELETE FROM history_alamat_mhs WHERE nim=OLD.nim;
-> END//
Query OK, 0 rows affected (0.63 sec)
mysql> DELIMITER ;

Penggunaan trigger trig_delete_mhs


mysql> SELECT * FROM history_alamat_mhs;
+---------------------+------------+------------------------+----------------+
| Waktu
| Nim
| Alamat
| Oleh
|
+---------------------+------------+------------------------+----------------+
| 2010-10-19 03:41:43 | 09.53.0042 | Jl. aa No.1
| root@localhost |
| 2010-10-19 03:42:32 | 09.53.1045 | Jl. bb No.2
| root@localhost |
| 2010-10-19 03:43:13 | 09.53.0062 | Jl. cc No.3
| root@localhost |
| 2010-10-19 03:50:41 | 09.53.1045 | Jl. Setiyasa 12 Madiun | root@localhost |
+---------------------+------------+------------------------+----------------+
mysql> SELECT * FROM mhs;
+------------+-----------------+---------------------------------------+
| Nim
| Nama
| Alamat
|
+------------+-----------------+---------------------------------------+
| 09.53.0042 | Septario Sagita | Ds. Lembah Jetis Rt 32/11 Madiun
|
| 09.53.0062 | Irfan Fajarufy | Jl. Ronggo Pustoko Rt 06 Rw 03 Madiun |
| 09.53.1045 | Tanto taufik N | Jl. Setiyasa 12a Madiun
|
+------------+-----------------+---------------------------------------+
mysql> DELETE FROM mhs where nim='09.53.1045';
Query OK, 1 row affected (0.68 sec)
mysql> SELECT * FROM mhs;
+------------+-----------------+---------------------------------------+
| Nim
| Nama
| Alamat
|
+------------+-----------------+---------------------------------------+
| 09.53.0042 | Septario Sagita | Ds. Lembah Jetis Rt 32/11 Madiun
|
| 09.53.0062 | Irfan Fajarufy | Jl. Ronggo Pustoko Rt 06 Rw 03 Madiun |
+------------+-----------------+---------------------------------------+
mysql> SELECT * FROM history_alamat_mhs;
+---------------------+------------+-------------+----------------+
| Waktu
| Nim
| Alamat
| Oleh
|
+---------------------+------------+-------------+----------------+
| 2010-10-19 03:41:43 | 09.53.0042 | Jl. aa No.1 | root@localhost |
| 2010-10-19 03:43:13 | 09.53.0062 | Jl. cc No.3 | root@localhost |
+---------------------+------------+-------------+----------------+

CONTOH 4
Membuat sebuah trigger yang mencegah perubahan pada primary key tabel mhs (field
nim). Jika ada perubahan, maka nim tidak boleh berubah. (agak kontradiksi dengan
contoh 2, tapi ngak masalah. Sekedar contoh). Hal ini dapat dilakukan yaitu dengan
mengeset nilai nim yang baru (NEW.nim) dengan nilai yang lama (OLD.nim)
mysql> DELIMITER //
mysql> DROP TRIGGER IF EXISTS trig_update_nim_mhs //
mysql> CREATE TRIGGER trig_update_nim_mhs
-> BEFORE UPDATE ON mhs
-> FOR EACH ROW
-> BEGIN
->
SET NEW.nim=OLD.nim;
-> END //
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;

Penggunaan trigger trig_update_nim_mhs


mysql> SELECT * FROM mhs;
+------------+-----------------+---------------------------------------+
| Nim
| Nama
| Alamat
|
+------------+-----------------+---------------------------------------+
| 09.53.0042 | Septario Sagita | Ds. Lembah Jetis Rt 32/11 Madiun
|
| 09.53.0062 | Irfan Fajarufy | Jl. Ronggo Pustoko Rt 06 Rw 03 Madiun |
+------------+-----------------+---------------------------------------+
mysql> UPDATE mhs SET nim='09.53.1042' WHERE nim='09.53.0042';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM mhs;


+------------+-----------------+---------------------------------------+
| Nim
| Nama
| Alamat
|
+------------+-----------------+---------------------------------------+
| 09.53.0042 | Septario Sagita | Ds. Lembah Jetis Rt 32/11 Madiun
|
| 09.53.0062 | Irfan Fajarufy | Jl. Ronggo Pustoko Rt 06 Rw 03 Madiun |
+------------+-----------------+---------------------------------------+

TUGAS ..!
Buatlah database dbTransfer yang mempunyai tabel Rekening dan tabel Transfer.
Tabel Rekening mempunyai field : No Int Primary Key, Nama Varchar(30) dan Saldo Double.
Tabel Transfer untuk menyimpan data transaksi transfer mempunyai field :
- NoTransaksi
: Int Auto_Increment Primary Key
- WaktuTransaksi
: DateTime
- NoRekPengirim
: Int
- NoRekPenerima
: Int
- BesarTransfer
: Double
mempunyai constraint foreign key sbb:
CONSTRAINT FK_Transfer1 FOREIGN KEY(NoRekPengirim) REFERENCES rekening(No),
CONSTRAINT FK_Transfer2 FOREIGN KEY(NoRekPenerima) REFERENCES rekening(No);

Buatlah trigger, jika ada penambahan data di tabel transfer (AFTER INSERT ON transfer),
maka akan mengupdate saldo pada rekening yang bersangkutan sesuai dengan BesarTransfer.
Mirip dengan stored procedure Transfer.
Setelah dibuat ikuti langkah-langkah berikut :
1) Isi kan data ke tabel rekening sbb:
mysql> INSERT INTO rekening(no,nama,saldo) values(1,'Irfan',1000000),
(2,'Tanto',2000000);

2) Percobaan ke-1 trigger, dengan mengisikan data ke tabel rekening sbb:


mysql> INSERT INTO transfer(WaktuTransaksi,NorekPengirim, NorekPenerima,BesarTransfer)
values('2010-11-02',1,2,100000);
mysql> select * from transfer;
+-------------+---------------------+---------------+---------------+---------------+
| NoTransaksi | WaktuTransaksi
| NoRekPengirim | NoRekPenerima | BesarTransfer |
+-------------+---------------------+---------------+---------------+---------------+
|
1 | 2010-11-02 00:00:00 |
1 |
2 |
100000 |
+-------------+---------------------+---------------+---------------+---------------+

3) Hasil dari percobaan ke-1 trigger, maka rekening no 1 akan berkurang 100.000 menjadi 900.000
sedangkan rekening no 2 akan bertambah 100.000 menjadi 2.100.000:
mysql> select * from rekening;
+----+-------+---------+
| No | Nama | Saldo
|
+----+-------+---------+
| 1 | Irfan | 900000 |
| 2 | Tanto | 2100000 |
+----+-------+---------+

4) Percobaan trigger dengan melakukan transfer untuk rekening no 3 maka akan terjadi
peringatan error Foreign Key karena rekening no 3 tidak ada di tabel rekening :
mysql> INSERT INTO transfer(WaktuTransaksi,NorekPengirim,NorekPenerima,BesarTransfer)
values('2010-11-02',1,3,100000);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`dbtransfer/transfer`, CONSTRAINT `FK_Transfer2` FOREIGN KEY (`NoRekPenerima`)
REFERENCES `rekening` (`No`))

5) Percobaan ke-2 trigger, dengan mengisikan data ke tabel transfer sbb:


mysql> INSERT INTO transfer(WaktuTransaksi,NorekPengirim,NorekPenerima,BesarTransfer)
values('2010-11-02',1,2,150000);
mysql> select * from transfer;
+-------------+---------------------+---------------+---------------+---------------+
| NoTransaksi | WaktuTransaksi
| NoRekPengirim | NoRekPenerima | BesarTransfer |
+-------------+---------------------+---------------+---------------+---------------+
|
1 | 2010-11-02 00:00:00 |
1 |
2 |
100000 |
|
2 | 2010-11-02 00:00:00 |
1 |
2 |
150000 |
+-------------+---------------------+---------------+---------------+---------------+

6) Hasil dari percobaan ke-2 trigger, maka rekening no 1 akan berkurang 150.000 menjadi 750.000
sedangkan rekening no 2 akan bertambah 150.000 menjadi 2.250.000:

6
mysql> select * from rekening;
+----+-------+---------+
| No | Nama | Saldo
|
+----+-------+---------+
| 1 | Irfan | 750000 |
| 2 | Tanto | 2250000 |
+----+-------+---------+

You might also like