The Magic of Trigger

database trigger after insert mysqlSalah satu business rule yang banyak dijumpai dalam aplikasi perkantoran adalah penyimpana data menggunakan skema table master-detail seperti data Purchase Order, Invoice dan sebagainya. Tantangannya adalah membuat sebuah field yang berisi summary nilai pembelian yang ada di dalam table detail. Misalkan ada data Purchase Order dengan 5 item masing-masing bernilai 1.000.000 rupiah maka akan ada field summary di table master yang berisikan nilai 5.000.000.

Business Rule seperti di atas dapat di-enforce di level aplikasi menggunakan code PHP, Java, atau .net. Namun dapat juga dilakukan di level database dengan menggunakan trigger. Untuk mencapainya silakan ikuti langkah-langkah berikut ini,

Pertama-tama kita buat table master dan table detail.

mysql> -----------------------------
mysql> -- buat table header
mysql> -----------------------------
mysql> create table header (
    ->   id int auto_increment primary key,
    ->   amount int default 0
    -> ) ;
Query OK, 0 rows affected (0.04 sec)
 
mysql> -----------------------------
mysql> -- buat table detail
mysql> -----------------------------
mysql> create table detail (
    ->   id int auto_increment primary key,
    ->   header_id int not null,
    ->   quantity int default 0,
    ->   unit_price int default 0,
    ->   foreign key (header_id) references header (id)
    -> ) ;
Query OK, 0 rows affected (0.03 sec)

Kemudian coba kita buatkan trigger untuk meng-handle aktifitas insert ke table detail. Logikanya adalah, setiap kali ada penginputan row baru ke table detail maka field amount di table master harus diubah.

mysql> -----------------------------
mysql> -- buat insert trigger untu tabel detail
mysql> -- amount di table header dihitung
mysql> -- berdasarkan perkalian quantity*unit_price
mysql> -----------------------------
mysql> delimiter |
mysql> create trigger trg_detail_insert
    -> after insert on detail
    -> for each row
    -> begin
    ->   update header
    ->   set amount = (
    ->     select sum(quantity*unit_price)
    ->     from detail where header_id = new.header_id )
    ->   where id = new.header_id ;
    -> end;
    -> |
Query OK, 0 rows affected (0.01 sec)
 
mysql> delimiter ; 

Untuk keperluan ujicoba, maka kita masukkan beberapa row record ke table master dan coba tampilkan untuk mengetahui isinya. Dan dapat terlihat bahwa amount masih bernilai 0 (nol)

mysql> -----------------------------
mysql> -- insert sampel data ke header
mysql> -- kemudian tampilkan
mysql> -----------------------------
mysql> insert into header(amount)
    -> values (0), (0), (0) ;
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> select * from header ;
+----+--------+
| id | amount |
+----+--------+
|  1 |      0 |
|  2 |      0 |
|  3 |      0 |
+----+--------+
3 rows in set (0.00 sec)
Kemudian coba kita masukkan beberapa row record data ke table detail dan coba tampilkan isinya.
mysql> -----------------------------
mysql> -- insert sampel data ke detail
mysql> -- kemudian tampilkan
mysql> -----------------------------
mysql> insert into detail (header_id, quantity, unit_price)
    -> values (1, 10, 100), (1, 2, 300),
    ->        (2, 1, 500), (2, 5, 300) ;
Query OK, 4 rows affected (0.04 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> select * from detail;
+----+-----------+----------+------------+
| id | header_id | quantity | unit_price |
+----+-----------+----------+------------+
|  3 |         1 |       10 |        100 |
|  4 |         1 |        2 |        300 |
|  5 |         2 |        1 |        500 |
|  6 |         2 |        5 |        300 |
+----+-----------+----------+------------+
4 rows in set (0.00 sec)

Setelah kita lihat data yang ada di table detail di atas, maka seharusnya trigger akan mengubah field amount yang ada di table master. jadi sekarang kita coba tampilkan isi table master seperti di bawah ini.

mysql> -----------------------------
mysql> -- coba tampilkan isi table header
mysql> -- seharusnya amount sudah berubah
mysql> -----------------------------
mysql> select * from header;
+----+--------+
| id | amount |
+----+--------+
|  1 |   1600 |
|  2 |   2000 |
|  3 |      0 |
+----+--------+
3 rows in set (0.00 sec)

Tadaaa....... Sukses.... BERHASIL !!!!

mysql> -----------------------------
mysql> -- YESS....... !!!
mysql> -- it works
mysql> -----------------------------
mysql>

Setelah ini masih ada beberapa hal yang dapat dikembangkan lagi, yaitu trigger untuk proses UPDATE detail, karena proses update di table detail seharusnya juga mengubah nilai amount yang ada di table master. Selain itu contoh di atas menggunakan database MySQL, sehingga teman-teman yang ingin menerapkannya di sistem RDBMS lain harus menyesuaikan kembali sintaks-nya.

Semoga tutorial ini bisa bermanfaat.

Category: