Wednesday, February 18, 2026

 


Kalau sudah lama main PL/SQL, pasti familiar dengan ini:

EXCEPTION WHEN OTHERS THEN NULL; END;

Kelihatan rapi.
Tidak error.
Procedure “aman”.

Tapi justru di situlah masalahnya.


Kenapa WHEN OTHERS Sering Dipakai?

Jawaban jujurnya:

  • Biar nggak error

  • Biar job tidak gagal

  • Biar user tidak komplain

Dan saya juga dulu sering pakai.
Sampai suatu hari… kena batunya.


Kasus Nyata

Ada job malam:

  • Tidak pernah gagal

  • Log bersih

  • Tapi data tidak lengkap

Setelah dicek:

  • Ada error constraint

  • Tapi tertelan oleh WHEN OTHERS THEN NULL

Job dianggap sukses.
Data diam-diam rusak.

Dan ini yang paling berbahaya.


Contoh Pola Berbahaya

BEGIN INSERT INTO orders_backup SELECT * FROM orders; EXCEPTION WHEN OTHERS THEN NULL; END;

Kalau gagal:

  • Tidak ada pesan

  • Tidak ada log

  • Tidak ada yang tahu

Kecuali… user komplain keesokan harinya.


WHEN OTHERS yang Lebih Bertanggung Jawab

Kalau memang harus pakai WHEN OTHERS,
minimal lakukan ini:

EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLERRM); RAISE; END;

Atau simpan ke tabel log:

EXCEPTION WHEN OTHERS THEN INSERT INTO error_log (error_date, error_message) VALUES (SYSDATE, SQLERRM); RAISE; END;

Sekarang:

  • Error tetap tercatat

  • Job tetap jujur gagal

  • Debugging jauh lebih mudah


Kapan WHEN OTHERS Masih Masuk Akal?

Ada kasus tertentu, misalnya:

  • Cleanup process

  • Logging tambahan

  • Error non-kritis yang memang boleh dilewati

Tapi tetap:

  • Jangan kosong

  • Selalu ada jejak


Kebiasaan Lama yang Saya Tinggalkan

Dulu saya sering mikir:

“Yang penting nggak error.”

Sekarang saya lebih takut:

“Error tapi nggak ketahuan.”

PL/SQL itu bukan cuma soal jalan,
tapi soal kejujuran sistem.


Prinsip Pribadi Sekarang

Kalau lihat kode:

  • WHEN OTHERS THEN NULL

Saya langsung bertanya:

  1. Error apa yang mau disembunyikan?

  2. Apa dampaknya kalau error ini terjadi?

  3. Siapa yang tahu kalau ini gagal?

Kalau tidak ada jawaban jelas,
biasanya kode itu perlu diubah.


Penutup

WHEN OTHERS itu alat terakhir,
bukan jalan pintas.

Lebih baik job gagal dengan jelas
daripada sukses tapi bohong.

Sampai catatan Rabu berikutnya 👋

Wednesday, February 11, 2026

 Kalau sudah lama ngoding PL/SQL, cursor itu terasa “alami”.

Rapi, terstruktur, dan kelihatan profesional.

Masalahnya… tidak selalu perlu.


Contoh Pola yang Dulu Sering Saya Pakai

FOR rec IN ( SELECT employee_id, salary FROM employees ) LOOP DBMS_OUTPUT.PUT_LINE(rec.employee_id || ' - ' || rec.salary); END LOOP;

Tidak salah.
Tapi sering kali overkill.


Kasus Nyata

Di satu proses report:

  • Datanya ribuan

  • Hasilnya cuma dipindahkan ke tabel lain

Tetap pakai cursor + loop.

Hasilnya:

  • Jalan

  • Tidak error

  • Tapi lambat


Alternatif yang Lebih Sederhana

Kalau tujuannya cuma memindahkan atau memproses data massal:

INSERT INTO report_table (employee_id, salary) SELECT employee_id, salary FROM employees;

Tanpa loop.
Tanpa cursor.
Lebih ramah performa.


Kapan Cursor Masih Masuk Akal?

Cursor masih penting kalau:

  • Ada logic kompleks per baris

  • Banyak IF / kondisi khusus

  • Proses per record memang beda-beda

Tapi kalau:

  • Logic sama

  • Datanya banyak

  • Bisa diselesaikan SQL

Cursor biasanya bukan pilihan terbaik.


Kesalahan yang Dulu Sering Saya Lakukan

Saya dulu sering mikir:

“Kalau pakai cursor, berarti lebih aman.”

Padahal:

  • Aman ≠ efisien

  • Rapi ≠ cepat

Setelah beberapa kali kena masalah performa,
saya mulai biasakan:

SQL dulu, cursor belakangan.


Prinsip Sederhana yang Sekarang Saya Pakai

Sebelum pakai cursor, saya selalu tanya:

  1. Bisa pakai satu SQL?

  2. Perlu loop?

  3. Datanya besar atau kecil?

Kalau jawabannya:

  • Bisa SQL

  • Tidak perlu loop

  • Data besar

👉 cursor saya coret.


Penutup

Cursor bukan musuh.
Tapi juga bukan solusi untuk semua hal.

PL/SQL itu soal memilih alat yang pas,
bukan sekadar yang paling familiar.

Sampai catatan Rabu berikutnya 👋

Wednesday, February 4, 2026

 Ini salah satu kebiasaan lama yang sering “lolos review”.

Procedure:

  • Jalan normal

  • Tidak error

  • Bahkan terasa aman

Padahal… dampaknya bisa panjang.


Contoh yang Sering Saya Temui

FOR rec IN ( SELECT order_id FROM orders WHERE status = 'NEW' ) LOOP UPDATE orders SET status = 'PROCESS' WHERE order_id = rec.order_id; COMMIT; END LOOP;

Secara logika:

  • Setiap data langsung disimpan

  • Kalau gagal, yang lain sudah aman

Secara sistem:
👉 ini mimpi buruk performa


Kenapa COMMIT di Loop Itu Bermasalah?

Setiap COMMIT:

  • Menulis redo log

  • Melepas undo

  • Sinkron ke disk

Kalau loop:

  • 1.000 baris → 1.000 COMMIT

  • 10.000 baris → 10.000 COMMIT

Tidak heran kalau:

  • I/O naik

  • Session lain melambat

  • Database terasa “berat”

Dan tidak ada error sama sekali.


“Tapi Saya Takut Datanya Setengah Jalan…”

Ini alasan paling sering.

Dan memang valid dalam kasus tertentu.

Tapi sebelum taruh COMMIT di loop, tanyakan dulu:

  1. Apakah datanya benar-benar besar?

  2. Apakah bisa di-rollback bersama?

  3. Apakah failure-nya sering?

Sering kali jawabannya: tidak.


Pola yang Lebih Aman

Kalau memungkinkan:

FOR rec IN ( SELECT order_id FROM orders WHERE status = 'NEW' ) LOOP UPDATE orders SET status = 'PROCESS' WHERE order_id = rec.order_id; END LOOP; COMMIT;

Atau lebih baik lagi:

UPDATE orders SET status = 'PROCESS' WHERE status = 'NEW'; COMMIT;

Satu commit.
Lebih bersih.
Lebih ringan.


Kapan COMMIT di Loop Masih Masuk Akal?

Ada, tapi jarang.

Biasanya kalau:

  • Proses sangat panjang (jam-an)

  • Data independen per baris

  • Failure sebagian masih bisa diterima

Dan itupun:

  • Commit per batch (misalnya tiap 1.000 baris)

  • Bukan setiap baris


Catatan Pengalaman Kerja

Saya pernah menemukan job malam yang:

  • Tidak pernah error

  • Tapi membuat backup melambat

Setelah dicek:

  • Ada COMMIT di loop

  • Data puluhan ribu

Setelah diubah:

  • Commit per batch

  • Waktu eksekusi turun drastis

  • Beban server lebih stabil


Prinsip yang Saya Pegang Sekarang

Kalau lihat:

  • COMMIT di loop
    dan

  • Data bukan kecil

Saya langsung curiga.

Bukan salah,
tapi sering tidak perlu.


Penutup

COMMIT itu penting,
tapi tempatnya juga penting.

PL/SQL bukan cuma soal “jalan atau tidak”,
tapi soal bagaimana dampaknya ke sistem.

Sampai catatan Rabu berikutnya 👋

Wednesday, January 28, 2026

 Ini tipe masalah yang paling bikin curiga.

  • Tidak ada error

  • Tidak ada rollback

  • Log kelihatan normal

Tapi:

  • Server terasa berat

  • Session banyak yang aktif

  • User mulai komplain “kok lambat?”

Dan parahnya, procedure-nya kelihatan biasa saja.


Awalnya Saya Juga Mengira “Mungkin Server Lagi Sibuk”

Procedure ini jalan otomatis (job):

BEGIN process_daily_data; END;

Tidak error.
Tidak warning.
Tapi setiap jam tertentu, performa database turun.


Setelah Dicek Lebih Dalam…

Ternyata di dalam procedure ada loop seperti ini:

FOR rec IN ( SELECT order_id FROM orders WHERE status = 'NEW' ) LOOP UPDATE orders SET status = 'PROCESS' WHERE order_id = rec.order_id; END LOOP;

Sekilas:

  • Aman

  • Jelas

  • Mudah dibaca

Tapi ada masalah besar.


Masalah Utamanya: UPDATE di Dalam Loop

Kalau data:

  • 10 baris → aman

  • 100 baris → masih oke

  • 10.000 baris → mulai terasa

  • 100.000 baris → server bisa “ngap”

Kenapa?

  • Setiap loop = 1 context switch

  • Oracle harus bolak-balik SQL ↔ PL/SQL

Dan ini tidak kelihatan dari sisi error.


Versi yang Lebih Sehat

Kalau logic-nya sederhana seperti ini, loop tidak dibutuhkan.

Cukup:

UPDATE orders SET status = 'PROCESS' WHERE status = 'NEW';

Satu statement.
Lebih cepat.
Lebih ringan.


“Tapi Logic Saya Lebih Rumit…”

Nah, ini biasanya alasan kenapa loop dipertahankan.

Kalau memang perlu proses massal, pertimbangkan:

  • BULK COLLECT

  • FORALL

Contoh singkat:

SELECT order_id BULK COLLECT INTO v_ids FROM orders WHERE status = 'NEW'; FORALL i IN v_ids.FIRST .. v_ids.LAST UPDATE orders SET status = 'PROCESS' WHERE order_id = v_ids(i);

Bukan paling cantik,
tapi jauh lebih ramah performa.


Catatan Pengalaman Kerja

Saya pernah nemu job harian yang:

  • Jalan 40 menit

  • Tidak pernah error

  • Dianggap “wajar”

Setelah diubah:

  • Loop dikurangi

  • UPDATE massal diprioritaskan

Waktu turun jadi kurang dari 5 menit.

Dan tidak ada perubahan logic bisnis sama sekali.


Prinsip Pribadi Saya Sekarang

Setiap lihat PL/SQL, saya selalu cek:

  1. Ada UPDATE / INSERT di dalam loop?

  2. Bisa dijadikan satu statement SQL?

  3. Perlu loop, atau cuma kebiasaan lama?

Kalau ketemu poin 1 + data besar,
biasanya di situlah biang masalahnya.


Penutup

Procedure yang “diam” bukan berarti aman.
Kadang justru dia:

  • Pelan-pelan

  • Konsisten

  • Tapi menggerogoti resource

PL/SQL itu bukan cuma soal benar atau salah,
tapi soal dampaknya ke database.

Sampai catatan Rabu berikutnya 👋

Wednesday, January 21, 2026

 ni catatan yang muncul setelah beberapa kali “kecolongan”.

Query kelihatan rapi.
Logic kelihatan bersih.
Tapi performanya… pelan pelan banget.

Dan penyebabnya hampir selalu sama:
function PL/SQL dipanggil di dalam query.


Contoh yang Kelihatannya Aman

SELECT employee_id, get_salary_grade(salary) FROM employees;

Function get_salary_grade kelihatan sederhana.
Dan waktu dites pakai 1–2 data, tidak ada masalah.

Masalahnya baru terasa saat:

  • Datanya ribuan

  • Query dipanggil berkali-kali

  • Atau dipakai di report


Apa yang Sebenarnya Terjadi?

Oracle akan:

  • Mengambil set data

  • Lalu memanggil function untuk setiap baris

Artinya:

  • 1.000 baris → 1.000 kali function dipanggil

  • 10.000 baris → 10.000 kali function dipanggil

Kalau di dalam function ada:

  • SELECT lain

  • IF bertingkat

  • Logic tambahan

Ya jelas terasa lambat.


Contoh Function yang Jadi Masalah

FUNCTION get_salary_grade(p_salary NUMBER) RETURN VARCHAR2 IS v_grade VARCHAR2(10); BEGIN SELECT grade INTO v_grade FROM salary_grade WHERE p_salary BETWEEN min_salary AND max_salary; RETURN v_grade; END;

Secara logika: benar.
Secara performa: berbahaya kalau dipanggil massal.


Alternatif yang Lebih Aman

Daripada function di query, sering kali lebih baik:

  • Pindahkan logic ke SQL langsung

  • Pakai JOIN

Contoh:

SELECT e.employee_id, g.grade FROM employees e JOIN salary_grade g ON e.salary BETWEEN g.min_salary AND g.max_salary;

Lebih panjang sedikit,
tapi:

  • Lebih jelas

  • Lebih cepat

  • Lebih mudah dianalisis optimizer


Catatan Pengalaman Kerja

Saya pernah nemu report yang:

  • Jalan hampir 15 menit

  • Server kelihatan sibuk

  • Tidak ada error

Setelah dicek:

  • Query utamanya simpel

  • Tapi ada 2 function PL/SQL di SELECT

Begitu logic-nya dipindah ke JOIN:
👉 waktu turun jadi di bawah 1 menit

Dan lucunya, kodenya malah jadi lebih “jujur”.


Kapan Function Masih Boleh Dipakai?

Bukan berarti function itu haram 😄

Masih aman kalau:

  • Dipanggil untuk 1 record

  • Dipakai di logic procedure, bukan query massal

  • Atau benar-benar deterministic & sederhana

Yang bahaya:
👉 function + query + data besar


Penutup

Function PL/SQL itu enak dibaca.
Tapi SQL optimizer tidak peduli kode kita cantik atau tidak.

Kalau performa mulai aneh:

  • Cek dulu

  • Ada function di SELECT atau WHERE nggak?

Sering kali jawabannya: ada.

Sampai catatan Rabu berikutnya 👋

Popular Posts