Sepanjang section ini kita telah menguasai peralatan yang lengkap: prosedur dengan parameter, variabel, percabangan, loop, cursor, handler error, dan function. Peralatan yang lengkap menimbulkan godaan yang nyata — kalau semua bisa dilakukan di dalam database, bukankah sebaiknya semua memang dilakukan di sana? Jawabannya tegas: tidak selalu. Stored program adalah pedang bermata dua yang mengubah database dari penyimpan data menjadi penjalankan logika, dan perubahan peran itu membawa konsekuensi nyata pada arsitektur, pengujian, dan jangka panjang proyek. Chapter penutup ini tidak mengajarkan sintaks baru; kita menimbang kapan stored programs benar-benar membantu, kapan justru membebani, lalu menutup dengan panduan praktis yang dipakai industri modern.

Membuktikan Keunggulan Inti: Logika Dekat Data #

Sebelum menimbang, mari kita lihat sekali lagi keunggulan paling objektif stored program dengan contoh kecil: menaikkan seluruh harga sebesar persentase tertentu. Kita siapkan latihan seperti biasa:

sql
DROP DATABASE IF EXISTS belajar_sp;
CREATE DATABASE belajar_sp;
USE belajar_sp;

Output yang Dihasilkan:

text
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
sql
CREATE TABLE produk (
  id INT PRIMARY KEY,
  nama VARCHAR(50) NOT NULL,
  harga DECIMAL(10,2) NOT NULL,
  stok INT NOT NULL
);

INSERT INTO produk (id, nama, harga, stok) VALUES
  (1, 'Kopi Gayo', 55000.00, 10),
  (2, 'Teh Melati', 25000.00, 20),
  (3, 'Gula Aren', 15000.00, 30),
  (4, 'Susu Kental', 8000.00, 40),
  (5, 'Kopi Toraja', 62000.00, 5);

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

Prosedur berikut menaikkan seluruh harga dalam satu panggilan:

sql
DROP PROCEDURE IF EXISTS naikkan_harga;
DELIMITER $$
CREATE PROCEDURE naikkan_harga(IN p_persen DECIMAL(5,2))
BEGIN
  UPDATE produk
  SET harga = ROUND(harga * (1 + p_persen / 100), 2);
  SELECT ROW_COUNT() AS baris_diubah;
END$$
DELIMITER ;
CALL naikkan_harga(10.00);
SELECT id, nama, harga FROM produk ORDER BY id;

Output yang Dihasilkan:

text
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------------+
| baris_diubah |
+--------------+
|            5 |
+--------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+----+-------------+----------+
| id | nama        | harga    |
+----+-------------+----------+
|  1 | Kopi Gayo   | 60500.00 |
|  2 | Teh Melati  | 27500.00 |
|  3 | Gula Aren   | 16500.00 |
|  4 | Susu Kental |  8800.00 |
|  5 | Kopi Toraja | 68200.00 |
+----+-------------+----------+
5 rows in set (0.00 sec)

Kelima harga naik sepuluh persen dalam satu panggilan jaringan. Bandingkan dengan versi aplikasi yang tidak memakai prosedur: aplikasi harus menjalankan SELECT untuk mengambil seluruh baris, mengalikan harga satu per satu di memorinya, lalu mengirim UPDATE untuk setiap baris — lima kali bolak-balik untuk lima produk, dan pada tabel sejuta baris artinya sejuta statement bermigrasi melalui jaringan padahal datanya tidak pernah keluar dari server. Semakin berat pemrosesan per baris dan semakin besar tabelnya, semakin lebar jurang antara kedua pendekatan — inilah argumen terkuat stored programs: memindahkan perhitungan ke tempat data tinggal.

Kapan Stored Programs Membantu #

Keunggulan di atas menyempit menjadi daftar situasi yang benar-benar diuntungkan:

  • Logika dipakai bersama lintas aplikasi. Rumus diskon atau aturan penomoran nota yang dipakai oleh aplikasi web, skrip laporan, dan pekerjaan cron akan tersalin tiga kali dalam tiga bahasa bila ditaruh di aplikasi; sebagai prosedur atau function, satu definisi melayani semuanya.
  • Batch berat data. Migrasi, rekap historis, dan pembersihan massal yang memproses jutaan baris berjalan jauh lebih cepat di server tanpa memindahkan satu baris pun ke luar — cursor, loop, dan handler yang kita latih adalah peralatan utamanya.
  • Validasi terpusat. Aturan SIGNAL SQLSTATE '45000' pada chapter Error Handling memastikan data buruk ditolak di gerbang terakhir, apa pun aplikasi yang mencoba memasukkannya.
  • Mengurangi hak akses mentah. Skrip maintenance bisa diberi izin EXECUTE pada satu prosedur tanpa izin UPDATE langsung pada tabel — permukaan serangan mengecil.
  • Laporan multi-langkah yang dipanggil sering. Rangkaian query berat yang dijalankan tiap menit oleh dashboard hemat bandwidth dan parsing ketika dikemas sebagai satu CALL.

Kapan Stored Programs Justru Membebani #

Di sisi lain, daftar biayanya panjang dan sering terasa setelah proyek membesar:

  • Bisnis logic menyebar ke dua tempat. Aturan bisnis yang tadinya utuh di aplikasi kini terbelah antara kode aplikasi dan tubuh prosedur; setiap perubahan aturan menuntut penyelarasan dua dunia dengan tooling berbeda.
  • Pengujian menyulit. Framework unit test modern (PHPUnit, pytest, JUnit) menguji kode aplikasi dengan mudah, namun menguji prosedur menuntut database hidup — test menjadi lambat dan jarang dikerjakan.
  • Keterikatan vendor. Sintaks stored program MySQL (handler 1062, SIGNAL 45000, cursor) tidak portabel ke PostgreSQL atau SQLite; migrasi database menjadi proyek penulisan ulang, bukan sekadar ganti connection string.
  • Version control tidak alami. Kode aplikasi hidup rapi di Git, sedangkan prosedur hidup sebagai objek di server — tanpa disiplin menyimpan berkas .sql dan prosedur deploy yang ketat, versi di server diam-diam menyimpang dari yang ada di repo.
  • Tim dan alat terbatas. Profiling, debugging step-by-step, dan code review yang lazim di bahasa aplikasi tidak semudah itu tersedia untuk SQL prosedural; tim kecil tanpa DBA khusus merasakan biaya ini paling dulu.

Menimbang dalam Satu Tabel #

SituasiKecenderunganAlasan singkat
Batch/migrasi jutaan barisgunakandata tidak perlu keluar server
Rumus dipakai lintas aplikasigunakansatu definisi, satu sumber kebenaran
Validasi integritas terakhirgunakanSIGNAL menjaga gerbang data
Aturan bisnis yang sering berubahhindaridua tempat harus disinkronkan tiap perubahan
Tim tanpa DBA, produk berkembang cepathindaribiaya pemeliharaan melebihi untung performa
Rencana migrasi database di horizonhindaristored program tidak portabel antar vendor

Keputusan nyata sering berada di antara kedua kutub — batch bulanan cocok jadi prosedur, sementara aturan diskon yang berubah tiap promo sebaiknya tetap di kode aplikasi yang mudah diuji dan digulirkan.

Pro dan Kontra dalam Ringkasan #

ProKontra
Performa untuk data beratPengujian lebih sulit
Konsistensi lintas aplikasiLogika terpecah dua tempat
Validasi di gerbang dataTerikat vendor
Hemat round-trip jaringanVersion control butuh disiplin
Permukaan hak akses mengecilTooling debug terbatas

Diagram di atas bukan hukum, melainkan titik awal diskusi: keputusan akhir selalu memperhitungkan kapasitas tim, umur sistem, dan arah arsitektur organisasi.

Panduan Praktis Modern #

Konsensus industri hari ini condong ke satu kalimat: jaga lapisan database tetap tipis. Database diberi pekerjaan yang paling tidak bisa dilakukan pihak lain — integritas data, batch berat, audit — sementara keputusan bisnis, orkestrasi, dan presentasi tinggal di kode aplikasi yang kaya tooling. Konsekuensi praktisnya untuk proyek kita:

  1. Default: logika di aplikasi. Stored program adalah optimasi atau penjaga integritas, bukan tempat pertama menulis bisnis logic.
  2. Simpan setiap prosedur dan function sebagai berkas .sql di repositori, dengan DROP ... IF EXISTS di awal seperti pola kita sepanjang section ini, sehingga deploy bisa diulang dan auditable.
  3. Sederhanakan yang bisa disederhanakan. Sebelum menulis loop + cursor, periksa apakah satu UPDATE ... JOIN atau query beragregat menyelesaikannya — SQL deklaratif sering mengalahkan prosedural.
  4. Uji stored program yang penting. Minimal panggil jalur sukses dan jalur gagal (SIGNAL) secara otomatis sebelum deploy.
  5. Batas kompleksitas. Prosedur yang melewati ratusan baris adalah sinyal kuat logika tersebut sebaiknya pindah ke aplikasi.

Membersihkan Database Latihan #

sql
DROP PROCEDURE naikkan_harga;
DROP DATABASE belajar_sp;

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Referensi #

Stored programs kini punya tempat yang jelas di peta keputusan kita: juara untuk batch berat, validasi terakhir, dan logika bersama; ditinggalkan untuk bisnis logic yang ramai berubah, tim tanpa DBA, dan sistem yang mungkin migrasi vendor. Peralatannya — DELIMITER, parameter, variabel, kontrol alur, cursor, handler, function — sudah teruji di tangan kita dan siap dipakai pada kasus yang tepat. Selanjutnya kita berkenalan dengan dua penghuni otomatis database: trigger yang menjaga setiap perubahan baris, dan event yang bekerja saat kita tidur — section Triggers dan Events menanti.