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 👋

Wednesday, January 14, 2026

 Pernah ngalamin ini?

  • Query dijalankan langsung → cepat

  • Query yang sama dimasukin ke procedure → kok lama?

Awalnya saya juga mikir:

“Ah, mungkin database lagi sibuk.”

Ternyata… sering kali bukan itu masalahnya.


Kasus Nyata yang Sering Terjadi

Query ini kalau dijalankan langsung:

SELECT * FROM orders WHERE order_date >= SYSDATE - 7;

Hasilnya cepat.
Tapi begitu dimasukkan ke procedure:

CREATE OR REPLACE PROCEDURE get_orders IS CURSOR c_orders IS SELECT * FROM orders WHERE order_date >= SYSDATE - 7; v_rec c_orders%ROWTYPE; BEGIN OPEN c_orders; LOOP FETCH c_orders INTO v_rec; EXIT WHEN c_orders%NOTFOUND; -- proses data END LOOP; CLOSE c_orders; END;

Dipanggil… dan terasa lambat.


Penyebab #1: Loop Baris per Baris (Row by Row)

Ini jebakan klasik PL/SQL.

Query SQL:

  • Diproses set-based

  • Dioptimasi oleh Oracle

Loop PL/SQL:

  • Diproses baris per baris

  • Jauh lebih berat kalau datanya banyak

Di dunia PL/SQL, ini sering disebut:

“Slow by Slow”


Penyebab #2: Terlalu Banyak Logic di Dalam Loop

Kadang tanpa sadar, di dalam loop kita taruh:

  • SELECT tambahan

  • IF bertingkat

  • UPDATE per baris

Contoh jebakan:

LOOP FETCH c_orders INTO v_rec; EXIT WHEN c_orders%NOTFOUND; SELECT status INTO v_status FROM customers WHERE customer_id = v_rec.customer_id; END LOOP;

Kalau cursor berisi 10.000 baris, berarti:
👉 10.000 SELECT tambahan


Penyebab #3: Cursor Padahal Bisa SQL Murni

Banyak logic yang sebenarnya bisa ditarik ke SQL langsung.

Daripada:

  • Cursor

  • Loop

  • Logic manual

Sering kali cukup:

INSERT INTO report_table SELECT ... FROM orders o JOIN customers c ON ... WHERE ...

Lebih singkat.
Lebih cepat.
Lebih ramah performa.


Catatan Pengalaman Kerja

Di satu project lama, ada procedure yang:

  • Jalan 20 menit

  • Server kelihatan “sibuk”

Setelah dicek:

  • Ada loop

  • Di dalamnya ada SELECT

  • Di dalam SELECT ada function PL/SQL lain

Setelah diubah ke SQL murni:
👉 Waktu turun jadi kurang dari 1 menit

Dan lucunya, logic-nya jadi lebih pendek.


Prinsip yang Selalu Saya Pegang

Kalau kerja pakai PL/SQL, saya selalu tanya ke diri sendiri:

  1. Ini bisa pakai SQL saja nggak?

  2. Ini perlu loop atau cuma kebiasaan lama?

  3. Ada SELECT di dalam loop?

Kalau jawabannya “iya”, biasanya di situ sumber lambatnya.


Penutup

PL/SQL itu kuat, tapi bukan berarti semua masalah harus diselesaikan dengan loop.

Kadang:

  • Kurang kode

  • Lebih SQL
    justru hasilnya lebih baik.

Catatan berikutnya kemungkinan bahas:

  • BULK COLLECT & FORALL (versi santai, bukan textbook)

  • Atau debugging procedure yang “diam tapi makan resource”

Sampai catatan Rabu berikutnya 👋

Wednesday, January 7, 2026

Kalau dipikir-pikir, error PL/SQL itu jarang yang benar-benar “aneh”.

Yang bikin lama biasanya justru hal kecil yang terlewat.

Dan ini biasanya kejadian kalau:

  • Sudah lama nggak pegang PL/SQL

  • Atau lagi buru-buru

  • Atau merasa “ini pasti gampang”

(Spoiler: justru di situ jebakannya 😅)


1️⃣ ORA-06502: Numeric or Value Error

Ini salah satu error yang paling sering saya temui… dan paling bikin mikir.

Contoh sederhana:

DECLARE v_name VARCHAR2(5); BEGIN v_name := 'ANDI SETIAWAN'; END;

Sekilas aman.
Tapi begitu dijalankan… boom 💥

Kenapanya simpel:

  • Panjang string lebih besar dari ukuran variabel

  • Tapi saat fokus ke logika, hal kecil ini sering luput

Pelajaran:
Kalau error ini muncul, cek ukuran variabel dulu, jangan langsung nuduh query.


2️⃣ SELECT INTO yang Ternyata Balik Lebih dari Satu Baris

Ini klasik.

DECLARE v_salary NUMBER; BEGIN SELECT salary INTO v_salary FROM employees WHERE department_id = 10; END;

Di kepala kita:

“Ah, cuma satu data kok.”

Di database:

“Ini ada 5 baris, bro.”

Akhirnya:

ORA-01422: exact fetch returns more than requested number of rows

Dan biasanya baru sadar setelah:

  • Cek data manual

  • Atau ditambah ROWNUM = 1 (yang kadang cuma jadi tambalan)


3️⃣ Lupa COMMIT, Padahal Procedure Jalan Normal

Ini bukan error, tapi jebakan mental.

Procedure jalan:

  • Tidak ada error

  • Output muncul

  • Tapi data… nggak berubah

Contoh:

BEGIN UPDATE employees SET salary = salary + 1000 WHERE employee_id = 101; END;

Dijalankan, sukses.
Tapi pas dicek ulang… datanya tetap sama.

Jawabannya sederhana:
👉 belum COMMIT

Lucunya, ini sering kejadian:

  • Di environment testing

  • Saat pindah dari aplikasi ke SQL Developer


4️⃣ Error karena NULL yang Tidak Disangka

PL/SQL dan NULL itu… hubungan cinta-benci.

IF v_total = 0 THEN DBMS_OUTPUT.PUT_LINE('Kosong'); END IF;

Kalau v_total ternyata NULL, kondisi ini tidak pernah true.

Padahal di kepala kita:

“Kalau kosong ya 0 dong.”

Nope.
PL/SQL beda cerita.

Solusi paling aman:

IF NVL(v_total, 0) = 0 THEN

Catatan Pengalaman

Di satu project lama, saya pernah:

  • Ngejar error berjam-jam

  • Fokus ke query yang panjang

  • Padahal penyebabnya cuma salah ukuran VARCHAR2

Sejak itu, setiap debug PL/SQL, saya selalu mulai dari:

  1. Ukuran variabel

  2. Jumlah data SELECT INTO

  3. NULL handling

  4. COMMIT / ROLLBACK

Baru ke logika rumit.


Penutup

PL/SQL itu jarang “jahat”.
Yang sering bikin lama justru asumsi kita sendiri.

Catatan minggu ini cuma pengingat:

sebelum menyalahkan Oracle, cek dulu hal-hal kecil.

Catatan berikutnya kemungkinan bahas:

  • Procedure lambat padahal query cepat

  • Atau loop yang diam-diam bikin performa jatuh

Sampai catatan berikutnya 👋

Wednesday, December 31, 2025

 Sudah lama sekali rasanya tidak buka blog ini.

Bahkan sempat lupa terakhir nulis apa dan tahun berapa 😅

Tapi anehnya, PL/SQL itu seperti sepeda. Lama nggak dipakai, begitu disentuh lagi… pelan-pelan ingat.

Blog ini dulu saya buat cuma sebagai catatan pribadi, bukan tutorial serius. Dan sepertinya, ke depan pun akan tetap seperti itu. Catatan kecil tentang PL/SQL, error yang bikin bengong, dan solusi yang kadang kelihatannya sepele tapi nyelametin waktu berjam-jam.


Kenapa PL/SQL Masih Saya Pakai Sampai Sekarang?

Jujur, di luar sana banyak bahasa yang lebih “seksi”.
Tapi di dunia kerja, terutama yang sudah pakai Oracle bertahun-tahun, PL/SQL masih hidup dan dipakai setiap hari.

Yang sering kejadian:

  • Aplikasi baru oke

  • Tapi backend-nya tetap bergantung ke stored procedure lama

  • Dan akhirnya… kita balik lagi ke PL/SQL


Contoh Kode Sederhana (yang Sering Terlupakan)

Ini contoh kecil, tapi surprisingly sering bikin error kalau sudah lama nggak ngoding:

DECLARE v_total NUMBER; BEGIN SELECT COUNT(*) INTO v_total FROM employees; DBMS_OUTPUT.PUT_LINE('Total data: ' || v_total); END;

Kelihatannya simpel.
Tapi kesalahan yang sering saya lakukan setelah lama vakum:

  • Lupa INTO

  • Salah urutan SELECT

  • Atau lupa aktifkan DBMS_OUTPUT 😅


Catatan Pengalaman Kerja

Di satu project, saya pernah buang waktu hampir 30 menit cuma karena:

  • Procedure jalan

  • Tidak error

  • Tapi tidak ada output apa-apa

Ternyata?
Session SQL Developer-nya belum SET SERVEROUTPUT ON.

Sepele, tapi kalau lagi dikejar deadline… bisa bikin emosi.


Penutup

Blog ini akan saya hidupkan lagi, pelan-pelan tapi konsisten.
Tidak janji artikel panjang atau super rapi, tapi saya janji:

  • Kode nyata

  • Error nyata

  • Pengalaman nyata

Kalau kamu juga masih berkutat dengan PL/SQL, mungkin catatan ini bisa sedikit membantu… atau minimal bikin kamu sadar:

“Oh, ternyata bukan gue doang yang pernah salah beginian.”

Sampai catatan berikutnya.

Tuesday, June 20, 2023

Pengantar singkat tentang PL/SQL (Procedural Language/Structured Query Language). 

PL/SQL adalah ekstensi dari SQL yang digunakan untuk membuat program yang menjalankan operasi database yang kompleks dan berjalan di dalam database Oracle.


Berikut ini adalah beberapa konsep dasar dalam PL/SQL:


Blok PL/SQL: Blok PL/SQL adalah unit dasar pemrograman dalam PL/SQL. Blok ini terdiri dari deklarasi, penanganan eksepsi (exception handling), dan bagian eksekusi.


Contoh blok PL/SQL:


DECLARE

   -- Deklarasi variabel

   nama_variabel datatype;

BEGIN

   -- Bagian eksekusi

   -- ...

EXCEPTION

   -- Penanganan eksepsi

   -- ...

END;


Variabel: Anda dapat mendeklarasikan variabel dalam blok PL/SQL. Variabel digunakan untuk menyimpan nilai sementara yang dapat digunakan dalam operasi selanjutnya.


Contoh deklarasi variabel:

DECLARE

   nama_variabel datatype;

BEGIN

   nama_variabel := nilai;

END;


Pengendalian alur: Anda dapat menggunakan pernyataan pengendalian alur seperti IF-THEN-ELSE, LOOP, dan CASE untuk mengontrol alur eksekusi program.


Contoh pengendalian alur IF-THEN-ELSE:

IF kondisi THEN

   -- Perintah yang dieksekusi jika kondisi bernilai TRUE

ELSE

   -- Perintah yang dieksekusi jika kondisi bernilai FALSE

END IF;

Prosedur dan Fungsi: Anda dapat membuat prosedur dan fungsi di PL/SQL. Prosedur adalah blok PL/SQL yang dapat dieksekusi, sedangkan fungsi mengembalikan nilai.


Contoh definisi prosedur:

CREATE OR REPLACE PROCEDURE nama_prosedur

IS

BEGIN

   -- Logika prosedur

END;


Contoh definisi fungsi:

CREATE OR REPLACE FUNCTION nama_fungsi

RETURN datatype

IS

BEGIN

   -- Logika fungsi

END;

Eksepsi: PL/SQL memiliki mekanisme penanganan eksepsi yang memungkinkan Anda untuk menangani kesalahan atau kondisi tidak normal dalam program Anda.


Contoh penanganan eksepsi:

BEGIN

   -- Logika program

EXCEPTION

   WHEN jenis_eksepsi THEN

      -- Penanganan kesalahan

END;


Ini hanya pengantar singkat tentang PL/SQL. Ada banyak konsep lain yang dapat dieksplorasi seperti penggunaan kursor, paket, dan trigger. Saya merekomendasikan Anda membaca dokumentasi resmi Oracle untuk mendapatkan pengetahuan yang lebih mendalam tentang PL/SQL.

Popular Posts