14/01/14

Trigger
Trigger adalah sebuah objek database yang diasosiasikan dengan sebuah tabel. Trigger diaktifkan ketika sebuah event terjadi pada tabel yang diasosiasikan. Tabel yang diasosiasikan dengan trigger haruslah sebuah tabel yang permanen dan bukan temporary tabel.

Membuat trigger
Trigger dibuat menggunakan sintaks sebagai berikut:
CREATE TRIGGER <trigger_name> <trigger_time> <trigger_event>
ON <table>
FOR EACH ROW <trigger_body statements>


Pada sintaks di atas, trigger_name adalah nama dari trigger yang akan kita buat. Trigger_time adalah saat aktivasi trigger. Parameter trigger_time dapat berisi BEFORE atau AFTER, yang menandakan apakah aktivasi trigger dilakukan sebelum atau sesudah terjadi perubahan pada tabel. Trigger_event menunjukkan jenis statement yang mengaktifkan trigger. Trigger_event dapat didefinisikan sebagai salah satu dari:
• INSERT: trigger diaktifkan ketika sebuah baris baru ditambahkan ke tabel, sebagai contoh
melalui statement INSERT, LOAD DATA, atau REPLACE.
• UPDATE: trigger diaktifkan ketika sebuah baris dimodifikasi, sebagai contoh melalui statement
UPDATE.
• DELETE: trigger diaktifkan ketika sebuah baris dihapus, melalui statement DELETE dan REPLACE.

Namun demikian, DROP TABLE dan TRUNCATE TABLE tidak mengaktifkan trigger DELETE Tidak boleh ada dua buah trigger yang sama pada sebuah tabel yang memiliki trigger_time dan trigger_event yang sama. Sebagai contoh, kita tidak dapat membuat dua buah BEFORE UPDATE trigger pada satu buah tabel yang sama, namun kita dapat membuat trigger BEFORE UPDATE dan AFTER UPDATE untuk satu tabel yang sama. trigger_body merupakan definisi statement yang dijalankan ketika sebuah trigger diaktifkan. Jika ada beberapa statement yang ingin dijalankan, statement-statement tersebut dapat didefinisikan di antara
BEGIN … AND. Keyword OLD dan NEW dapat digunakan untuk mereferensi nilai sebelum dan sesudah trigger dilakukan. Sebagai contoh OLD.nama_kolom menunjukkan nilai kolom sebelum data tersebut dihapus atau diupdate, sedangkan NEW.nama_kolom menunjukkan nilai kolom sebuah data yang akan
dimasukkan atau nilai kolom data setelah diupdate. 

BEFORE TRIGGER 
Berikut adalah contoh trigger yang dijalankan sebelum data dimasukkan ke dalam sebuah tabel. 

mysql> DELIMITER //
mysql> CREATE TRIGGER before_insert BEFORE INSERT ON employee
-> FOR EACH ROW
-> BEGIN
-> IF NEW.salary IS NULL OR NEW.salary = 0 THEN
-> SET NEW.salary = 1000;
-> ELSE
-> SET NEW.salary = NEW.salary + 100;
-> END IF;
-> END //
Query OK, 0 rows affected (0.13 sec)
mysql> DELIMITER ;


Pada contoh di atas, kita membuat trigger before insert yang akan dijalankan sebelum INSERT dilakukan
ke tabel employee. Trigger ini akan mengganti nilai salary jika salary yang dimasukkan dalam INSERT
bernilai NULL atau 0 dan menambahkan 100 jika selainnya. Berikut adalah contoh memasukkan data
setelah didefinisikan trigger.

mysql> insert into employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values (1,'John', 'Doe', '19960725', '20060725', 0, 'Canberra', 'Programmer');
Query OK, 1 row affected (0.40 sec)
mysql> SELECT * FROM employee WHERE first_name = 'John';
+----+------------+-----------+------------+------------+---------+----------+-------------+
| id | first_name | last_name | start_date | end_date   | salary  | city     |description  |
+----+------------+-----------+------------+------------+---------+----------+-------------+
| 1  |       John |       Doe | 1996-07-25 | 2006-07-25 | 1000.00 | Canberra | Programmer  |
+----+------------+-----------+------------+------------+---------+----------+-------------+
1 rows in set (0.00 sec)

Namun demikian, kita tidak dapat mengupdate tabel yang sama dengan tabel yang diasosiasikan
dengan trigger menggunakan trigger.

mysql> DELIMITER &&
mysql> CREATE TRIGGER before_update BEFORE UPDATE ON employee
-> FOR EACH ROW
-> BEGIN
-> UPDATE employee SET salary = salary+(NEW.salary - OLD.salary)
-> WHERE id = NEW.id;
-> END &&
Query OK, 0 rows affected (0.13 sec)
mysql> DELIMITER ;
mysql> UPDATE employee SET salary = 1000 WHERE id = 1;
ERROR 1442 (HY000): Can't update table 'employee' in stored function/trigger because it
is already used by statement which invoked this stored function/trigger.


AFTER TRIGGER
Berikut adalah contoh trigger yang dijalankan setelah update dilakukan terhadap tabel.
mysql> CREATE TABLE trans_log(
-> user_id VARCHAR(15),
-> description VARCHAR(50)
-> );
Query OK, 0 rows affected (0.16 sec)

Query di atas digunakan untuk membuat tabel trans_log. Tabel ini akan digunakan untuk mencatat perubahan yang terjadi pada kolom salary pada tabel employee.
mysql> DELIMITER $$
mysql> CREATE TRIGGER log_salary AFTER UPDATE
-> ON employee
-> FOR EACH ROW
-> BEGIN
-> INSERT INTO trans_log
-> VALUES (user(), CONCAT('merubah akun ',NEW.id,' dari ',OLD.salary, ' to
',NEW.salary));
-> END $$
Query OK, 0 rows affected (0.12 sec)
mysql> DELIMITER ;

Pada query di atas, kita membuat trigger setelah update. Ketika update pada tabel employee
dijalankan, perubahan nilai salary akan dicatat dalam tabel trans_log.
mysql> UPDATE employee SET salary = salary + 1000;
Query OK, 15 rows affected (0.13 sec)
Rows matched: 15 Changed: 15 Warnings: 0
mysql> SELECT * FROM trans_log;
+----------------+-----------------------------------------+
| user_id | description |
+----------------+-----------------------------------------+
| root@localhost | merubah akun 1 dari 1000.00 to 2000.00 |
| root@localhost | merubah akun 2 dari 6662.78 to 7662.78 |
| root@localhost | merubah akun 3 dari 6545.78 to 7545.78 |
| root@localhost | merubah akun 4 dari 2345.78 to 3345.78 |
| root@localhost | merubah akun 5 dari 2335.78 to 3335.78 |
| root@localhost | merubah akun 6 dari 4323.78 to 5323.78 |
| root@localhost | merubah akun 7 dari 7898.78 to 8898.78 |
| root@localhost | merubah akun 10 dari 4313.98 to 5313.98 |
| root@localhost | merubah akun 11 dari 3213.98 to 4213.98 |
| root@localhost | merubah akun 12 dari 4124.21 to 5124.21 |
| root@localhost | merubah akun 13 dari 3000.00 to 4000.00 |
| root@localhost | merubah akun 14 dari 4500.00 to 5500.00 |
| root@localhost | merubah akun 15 dari 4500.00 to 5500.00 |
| root@localhost | merubah akun 16 dari 3500.00 to 4500.00 |
| root@localhost | merubah akun 17 dari 3500.00 to 4500.00 |
+----------------+-----------------------------------------+
15 rows in set (0.00 sec)

Contoh di atas mencoba melakukan update terhadap salary tabel employee. Ketika update terjadi, perubahan akan dicatat dalam tabel trans_log.

Melihat trigger yang sudah dibuat
Trigger yang telah dibuat dapat dilihat menggunakan command SHOW TRIGGERS. Contoh berikut menunjukkan bagaimana melihat trigger pada database PRAK2.
mysql> SHOW TRIGGERS IN PRAK2\G
*************************** 1. row ***************************
Trigger: before_insert
Event: INSERT
Table: employee
Statement: BEGIN IF NEW.salary IS NULL OR NEW.salary = 0 THEN SET
NEW.salary = 1000; ELSE SET NEW.salary = NEW.salary + 100; END IF; END
Timing: BEFORE
Created: NULL
sql_mode:
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
*************************** 2. row ***************************
Trigger: log_salary
Event: UPDATE
Table: employee
Statement: BEGIN INSERT INTO trans_log VALUES (user(),
CONCAT('merubah akun ',NEW.id,' dari ',OLD.salary, ' to ',NEW.salary)); END
Timing: AFTER
Created: NULL
sql_mode:
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
2 rows in set (0.00 sec)

Menghapus Trigger
Trigger yang telah dibuat dapat dihapus dengan menggunakan command DROP TRIGGER, seperti yang ditunjukkan oleh contoh berikut:
mysql> DROP TRIGGER before_insert;
Query OK, 0 rows affected (0.08 sec)
mysql> SHOW TRIGGERS IN PRAK2\G
*************************** 1. row ***************************
Trigger: log_salary
Event: UPDATE
Table: employee
Statement: BEGIN INSERT INTO trans_log VALUES (user(),
CONCAT('merubah akun ',NEW.id,' dari ',OLD.salary, ' to ',NEW.salary)); END
Timing: AFTER
Created: NULL
sql_mode:
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
1 row in set (0.00 sec)

2 komentar :