Penyimpana Data
END;
Konsep Prosedural 47
Contoh
/*Prosedur pengecekan stok lemari es*/ CREATE OR REPLACE PROCEDURE prc_stok_brg IS
v_stok INTEGER; BEGIN
-- Mengambil nilai stok dari barang lemari es -- (nilai stok adalah bilangan positif) SELECT stok_barang INTO v_stok FROM barang WHERE UPPER(nama_barang) = UPPER(‘lemari es’);
--Memeriksa nilai dari variabel v_stok IF v_stok = 0 THEN
--Jika v_stok = 0, cetak keterangan ke layar DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’);
END IF; END;
4.2.2 Fungsi
Fungsi adalah blok PL/SQL yang dapat mengembalikan nilai. Karena itu perlu ditambahkan statemen RETURN untuk proses pengembalian nilai.
CREATE [OR REPLACE] FUNCTION nama_fungsi (parameter1 tipedata, parameter2 tipedata,...) RETURN tipe_data_fungsi IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ... RETURN nilai_fungsi;
END;
Contoh
/*Fungsi pencarian nama supplier*/ CREATE OR REPLACE FUNCTION cari_supp
(pi_kode VARCHAR2) RETURN supplier.nama_supp%TYPE IS
v_NamaSupp supplier.nama_supp%TYPE;
BEGIN
-- Mengambil nama supplier berdasar parameter SELECT nama_supp INTO v_NamaSupp FROM supplier WHERE UPPER(kode_supp) = UPPER(pi_kode);
-- Mengembalikan nilai RETURN v_NamaSupp;
END;
4.2.3 Trigger
Trigger adalah blok PL/SQL yang disimpan dalam database dan akan diaktivasi ketika melakukan statemen-statemen SQL (INSERT, DELELTE, atau UPDATE) terhadap sebuah tabel. Aktivasi trigger didasarkan pada event yang terjadi pada tabel tersebut.
CREATE [OR REPLACE] TRIGGER nama_trigger BEFORE|AFTER [INSERT|DELETE|UPDATE] ON nama_tabel FOR EACH ROW
DECLARE -- berisi deklarasi variabel BEGIN -- berisi statemen-statemen yang akan dieksekusi END;
Konsep Prosedural 49
Kemungkinan event yang dapat mengaktivasi sebuah trigger adalah :
Nama Event Deskripsi
BEFORE INSERT Diaktifkan sekali sebelum statemen INSERT AFTER INSERT
Diaktifkan sekali setelah statemen INSERT BEFORE UPDATE Diaktifkan sekali sebelum statemen UPDATE AFTER UPDATE
Diaktifkan sekali setelah statemen UPDATE BEFORE DELETE Diaktifkan sekali sebelum statemen DELETE AFTER DELETE
Diaktifkan sekali setelah statemen DELETE
Contoh
/*Trigger yang diaktivasi setelah UPDATE*/ CREATE OR REPLACE TRIGGER trg_upd_barang
AFTER UPDATE ON barang FOR EACH ROW
BEGIN
-- Mencetak keterangan ke layar tiap kali terjadi -- update terhadap tabel barang DBMS_OUTPUT.PUT_LINE(‘Tabel
barang telah
diupdate’);
END;
4.3 Naming Convention yang Baik
Naming convention yang tepat akan membuat kode statemen PL/SQL lebih mudah dibaca dan lebih bisa dimengerti. Secara singkat, keuntungan dari naming convention yang baik adalah :
o Lebih mudah dibaca. o Lebih mudah dipahami. o Memberikan informasi mengenai fungsionalitas berdasarkan identifier. o Kemudahan dalam proses debug. o Memastikan konsistensi di antara banyak kode yang dibuat oleh
developer yang berbeda.
Beberapa contoh naming convention berdasar identifier :
Identifier Convention Contoh
Variabel v_prefix v_product_name Konstanta c_prefix
c_tax
Parameter p_prefix
p_cust_id
Exception e_prefix e_chk_credit_limit Cursor
cur_prefix cur_orders Type
typ_prefix typ_customer Trigger
trg_prefix trg_ins_customer
Konsep Prosedural 51
Rangkuman
1. Konsep prosedural dalam PL/SQL (Procedural Language extensions to SQL) merupakan sebuah teknologi yang memungkinkan kita membuat blok program layaknya dalam bahasa pemrograman prosedural.
IF … THEN SQL; ELSE
Aplikasi
SQL; END IF;
2. RPC (Remote Procedure Call) : pemanggilan progam unit (prosedur maupun fungsi) terhadap database.
RPC
Aplikasi
3. Program unit merupakan kontainer sekumpulan kode atau statemen : Prosedur : blok PL/SQL yang menyimpan sekumpulan perintah tanpa
disertai pengembalian nilai.
CREATE [OR REPLACE] PROCEDURE nama_prosedur (parameter1 tipedata, parameter2 tipedata,...) IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ...
END;
Fungsi : blok PL/SQL yang dapat mengembalikan nilai.
CREATE [OR REPLACE] FUNCTION nama_fungsi (parameter1 tipedata, parameter2 tipedata,...) RETURN tipe_data_fungsi IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ... RETURN nilai_fungsi;
END;
Trigger : blok PL/SQL yang disimpan dalam database dan akan diaktivasi ketika melakukan statemen-statemen SQL terhadap sebuah tabel.
CREATE [OR REPLACE] TRIGGER nama_trigger BEFORE|AFTER [INSERT|DELETE|UPDATE] ON nama_tabel FOR EACH ROW
DECLARE -- berisi deklarasi variabel BEGIN -- berisi statemen-statemen yang akan dieksekusi END;
4. Keuntungan dari naming convention yang baik adalah : Lebih mudah dibaca.
Lebih mudah dipahami. Memberikan informasi mengenai fungsionalitas berdasarkan
identifier. Kemudahan dalam proses debug. Memastikan konsistensi di antara banyak kode yang dibuat oleh
developer yang berbeda.
Konsep Prosedural 53
Kuis Benar Salah
1. RPC (Remote Procedure Call) adalah proses pemanggilan stored procedure atau function pada database oleh aplikasi client.
2. Blok PL/SQL berikut : BEGIN
END; Akan menghasilkan error.
3. Perbedaan antara prosedur dan fungsi adalah pada proses pengembalian nilai pada saat pemanggilan.
4. Trigger akan diaktivasi untuk setiap proses INSERT, DELETE, maupun UPDATE terhadap table apabila pada trigger tersebut tidak dispesifikasikan event apa yang bisa mengaktivasinya.
(Tanpa memperhatikan naming convention, untuk soal nomor 5 – 6 perhatikan prosedur berikut)
CREATE OR REPLACE PROCEDURE prc_upd_bil IS bil
INTEGER := 3; BEGIN bil := 5; DBMS_ OUTPUT.PUT_LINE(‘Nilai bil = ’ ||bil); END IF;
END;
5. bil adalah sebuah konstanta bertipe integer.
6. execute prc_upd_bil;
Akan menghasilkan output : Nilai bil = 5
(Tanpa memperhatikan naming convention, untuk soal nomor 7 – 9 perhatikan fungsi berikut)
CREATE OR REPLACE FUNCTION put_nama (pi_nama VARCHAR2) RETURN VARCHAR2 IS
nama VARCHAR2(10);
BEGIN RETURN nama; END;
7. SET serveroutput ON; DECLARE
coba VARCHAR2(10); BEGIN coba := put_nama('12345'); DBMS_OUTPUT.PUT_LINE(coba);
END;
Akan menghasilkan output : 12345
8. SET serveroutput ON; DECLARE
coba VARCHAR2(10); BEGIN coba := put_nama(12345); DBMS_OUTPUT.PUT_LINE(coba);
END;
Akan menghasilkan output : 12345
Konsep Prosedural 55
9. SET serveroutput ON; DECLARE
coba VARCHAR2(10); BEGIN coba := put_nama(‘123412341234’); DBMS_OUTPUT.PUT_LINE(coba);
END;
Akan menghasilkan output : 123412341234
10. Prefix pada naming convention sebuah identifier dapat memberikan informasi mengenai fungsionalitas identifier tersebut.
Pilihan Ganda
1. Pengeksekusian statemen SQL dalam database dapat dilakukan dengan cara :
A. Sintaks SQL
D. B dan C benar
B. Blok PL/SQL
E. A, B, dan C benar
C. RPC
2. Berikut adalah beberapa jenis program unit, kecuali :
A. prosedur
D. trigger
B. fungsi
E. package
C. table
3. Blok PL/SQL yang membutuhkan event untuk mengaktivasinya disebut :
A. prosedur
D. trigger
B. fungsi
E. package
C. table
4. Blok PL/SQL yang membutuhkan statement RETURN adalah :
A. prosedur
D. trigger
B. fungsi
E. package
C. table
5. Keuntungan dari pengaturan naming convention adalah sebagai berikut, kecuali :
A. Executable
D. Informative
B. Readable
E. Consistency
C. Understandable
Konsep Prosedural 57
(Tanpa memperhatikan naming convention, untuk soal nomor 6 – 8 perhatikan blok PL/SQL berikut)
SET serveroutput ON; DECLARE
coba INTEGER; BEGIN coba := 5**3; DBMS_OUTPUT.PUT_LINE(coba);
END;
6 Output dari blok PL/SQL di atas adalah :
E. Error
C. 0
7 Bila baris statemen : coba INTEGER; Diganti menjadi : coba DECIMAL (3,2);
Maka outputnya menjadi :
E. Error
8 Pada baris statemen : coba INTEGER;
coba merupakan sebuah :
A Variabel
D Cursor
B Konstanta
E Type
C Parameter
(Untuk soal nomor 9 - 10 perhatikan trigger berikut)
CREATE OR REPLACE TRIGGER trg_coba BEFORE UPDATE ON barang FOR EACH ROW
BEGIN UPDATE barang SET jumlah = 10;
END;
9 Bila dilakukan eksekusi : UPDATE barang
SET jumlah = 20;
Maka setelah eksekusi statemen di atas, field jumlah akan bernilai :
10 Bila statemen eksekusi ditambah menjadi : UPDATE barang SET jumlah = 20 WHERE nama_brg = ‘Lemari Es’;
Maka setelah eksekusi statemen di atas, field jumlah akan bernilai :
A 10, untuk semua jenis barang
D 20, untuk jenis barang Lemari Es
B 20, untuk semua jenis barang
E 30, untuk jenis barang Lemari Es
C 30, untuk semua jenis barang
Konsep Prosedural 59
Latihan
6. Sebutkan perbedaan antara prosedur, fungsi, dan trigger. Dan tuliskan sintaks masing-masing.
7. Sebutkan 5 keuntungan dari naming convention yang baik.
(Untuk soal nomor 3 - 4 perhatikan prosedur berikut)
CREATE OR REPLACE PROCEDURE prc_cetak_bil IS bil
INTEGER := 5; BEGIN -- statemen cetak bilangan ganjil ... -- statemen cetak bilangan genap ...
END;
8. Pada blok : -- statemen cetak bilangan ganjil
... tambahkan statemen SQL untuk mencetak bilangan ganjil antara 1
hingga 5.
9. Pada blok : -- statemen cetak bilangan genap
... tambahkan statemen SQL untuk mencetak bilangan genap antara 1
hingga 5. (Untuk soal nomor 5 - 6 perhatikan fungsi
berikut)
CREATE OR REPLACE FUNCTION cek_prima (pi_bil INTEGER) RETURN BOOLEAN IS
ket BOOLEAN;
BEGIN -- statemen cek bilangan prima ... -- akan mengembalikan TRUE bila merupakan -- bilangan prima, dan FALSE bila bukan ...
END;
10. Pada statemen : ket
BOOLEAN; Tambahkan inisialisasi nilai variabel dengan nilai awal adalah FALSE.
11. Pada blok : -- statemen cek bilangan prima ...
tambahkan statemen SQL untuk meng-update nilai variabel ket menjadi TRUE bila bilangan yang dimasukkan adalah bilangan prima.
12. Mengembalikan nilai variabel ket sebagai nilai balikan fungsi cek_prima.
(Untuk soal nomor 8 - 10 perhatikan trigger berikut)
CREATE OR REPLACE TRIGGER trg_delete -- deklarasi event terhadap table ... FOR EACH ROW
BEGIN -- statemen yang diaktivasi saat event terjadi ...
-- menampilkan keterangan ke layar ...
END;
Konsep Prosedural 61
13. Pada blok : -- deklarasi event terhadap table
... tambahkan deklarasi bahwa trigger akan teraktivasi setelah terjadi proses delete terhadap salah satu row di table barang.
14. Pada blok : -- statemen yang diaktivasi saat event terjadi ...
tambahkan statemen DELETE untuk nama_brg yang mengandung kata ‗Lemari‘ (gunakan operator LIKE dan fungsi UPPER).
15. Pada blok : -- menampilkan keterangan ke layar
... tambahkan statemen untuk mencetak keterangan ke layar bahwa proses
DELETE berhasil dilakukan.
5 Lebih Lanjut Mengenai Prosedural
-Percabangan-
Overview
Pada sebuah blok PL/SQL dapat ditempatkan suatu kontrol untuk pengecekan yang dilakukan sebelum statemen-statemen dalam blok PL/SQL dieksekusi. Kontrol inilah yang kemudian disebut sebagai percabangan (decision control / branching). Secara garis besar terdapat dua statemen percabangan : statemen IF dan statemen CASE.
Tujuan
1. Mahasiswa memahami konsep percabangan.
2. Mahasiswa memahami berbagai jenis statemen percabangan.
3. Mahasiswa dapat menerapkan berbagai jenis percabangan dalam blok PL/SQL.
Lebih Lanjut Mengenai Prosedur 63
5.1 Struktur Percabangan
Percabangan (decision control / branching) adalah suatu kontrol untuk pengecekan yang dilakukan sebelum statemen-statemen dalam sebuah blok PL/SQL dieksekusi. Statemen-statemen tersebut hanya akan dilakukan apabila kondisi yang didefinikan terpenuhi (bernilai TRUE). Dan sebaliknya, statemen- statemen tersebut tidak akan dieksekusi apabila kondisi tidak terpenuhi (bernilai FALSE).
Selain definisi di atas, percabangan juga bisa dikatakan sebagai pemilihan : blok PL/SQL akan memilih statemen-statemen yang akan dieksekusi berdasarkan kondisi yang terpenuhi.
Secara garis besar, terdapat dua cara untuk melakukan percabangan, yaitu dengan menggunakan statemen IF dan statemen CASE.
5.1.1 Statemen IF
Penggunaan statemen IF dapat diklasifikasikan ke dalam tiga bagian, yaitu struktur untuk satu kondisi, dua kondisi, dan tiga kondisi atau lebih.
5.1.1.1 Satu Kondisi (IF-THEN)
IF kondisi THEN statemen-statemen; END IF;
Pada struktur ini, PL/SQL hanya akan mengecek sebuah kondisi. Apabila kondisi tersebut terpenuhi (bernilai TRUE) maka statemen-statemen dalam blok pemilihan tersebut akan dieksekusi terlebih dulu sebelum dilanjutkan ke statemen di bawah blok pemilihan. Akan tetapi bila kondisi tidak terpenuhi (bernilai FALSE) maka eksekusi akan langsung berpindah ke statemen di bawah blok pemilihan.
Contoh
/*Prosedur pengecekan stok lemari es*/ CREATE OR REPLACE PROCEDURE prc_stok_brg IS
v_stok INTEGER; BEGIN
-- Mengambil nilai stok dari barang lemari es -- (nilai stok adalah bilangan positif) SELECT stok_barang INTO v_stok FROM barang WHERE UPPER(nama_barang) = UPPER(‘lemari es’);
--Memeriksa nilai dari variabel v_stok IF v_stok = 0 THEN
--Jika v_stok = 0, cetak keterangan ke layar DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’);
END IF; END;
SQL> set serveroutput on; SQL> exec prc_stok_brg;
Keterangan - IF v_stok = 0 THEN
DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’); END IF;
Sintak tersebut berarti dilakukan pengecekan : jika jumlah lemari es bernilai nol, maka ditampilkan ―Persediaan barang telah habis‖ (agar perintah DBMS_OUTPUT.PUT_LINE dapat dieksekusi, variabel SERVEROUTPUT harus diaktifkan). Jika stok barang tidak nol maka pengecekan kondisi tidak
Lebih Lanjut Mengenai Prosedur 65 Lebih Lanjut Mengenai Prosedur 65
5.1.1.2 Dua Kondisi (IF-THEN-ELSE)
IF kondisi THEN statemen-statemen A; ELSE statemen-statemen B; END IF;
Pada struktur ini, perlu didefinikan kondisi khusus untuk mengatasi apabila kondisi yang didefinisikan pada blok IF tidak terpenuhi. Kondisi khusus tersebut diletakkan pada bagian ELSE.
Apabila kondisi IF terpenuhi (bernilai TRUE) maka statemen-statemen
A akan dieksekusi terlebih dulu sebelum dilanjutkan ke statemen yang berada di bawah blok pemilihan. Bila kondisi IF tidak terpenuhi (bernilai FALSE) maka statemen-statemen B yang akan dieksekusi terlebih dulu sebelum dilanjutkan ke statemen yang berada di bawah blok pemilihan.
Contoh
/*Prosedur pengecekan stok lemari es*/ CREATE OR REPLACE PROCEDURE prc_stok_brg IS
v_stok INTEGER; BEGIN
-- Mengambil nilai stok dari barang lemari es -- (nilai stok adalah bilangan positif) SELECT stok_barang INTO v_stok FROM barang WHERE UPPER(nama_barang) = UPPER(‘lemari es’);
--Memeriksa nilai dari variabel v_stok IF v_stok = 0 THEN
--Jika v_stok = 0, cetak keterangan ke layar DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’);
ELSE
--Jika v_stok > 0, cetak keterangan ke layar DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang masih ada ’);
END IF; END;
SQL> set serveroutput on; SQL> exec prc_stok_brg;
Keterangan - IF v_stok = 0 THEN
DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’); ELSE DBMS_OU TPUT.PUT_LINE(‘Persediaan barang masih ada ’); END IF;
Sintak tersebut berarti dilakukan pengecekan : jika jumlah lemari es bernilai nol, maka ditampilkan kalimat ―Persediaan barang telah habis‖. Jika stok barang ternyata tidak nol maka pengecekan kondisi IF tidak terpenuhi dan pengecekan akan memenuhi kondisi ELSE, artinya statemen dalam blok ELSE akan dieksekusi sehingga kalimat ―Persediaan barang masih ada‖ yang akan dicetak ke layar.
5.1.1.3 Tiga Kondisi atau Lebih Kondisi (IF-THEN- ELSIF)
IF kondisi_1 THEN statemen-statemen A; ELSIF kondisi_2 THEN statemen-statemen B; ... ELSIF kondisi_n THEN
statemen-statemen N; [ELSE statemen-statemen lain;] END IF;
Lebih Lanjut Mengenai Prosedur 67
Pada struktur ini, minimal terdapat dua kondisi yang harus diperiksa dan satu tambahan kondisi khusus yang akan mengatasi kejadian dimana semua kondisi yang didefinisikan tidak terpenuhi (bernilai FALSE).
Mula-mula dilakukan pengecekan terhadap kondisi_1, jika TRUE maka statemen-statemen A akan dieksekusi dan kemudian mengeksekusi statemen yang berada di bawah blok pemilihan. Tapi bila FALSE maka akan dilakukan pengecekan selanjutnya untuk kondisi_2. Jika kondisi_2 TRUE maka statemen-statemen B akan dieksekusi sebelum statemen di bawah blok pemilihan dieksekusi, dan seterusnya. Apabila seluruh kondisi ELSIF tidak terpenuhi, maka statemen pada blok ELSE yang akan dieksekusi.
Contoh
/*Prosedur untuk menaikkan gaji pegawai*/ CREATE OR REPLACE PROCEDURE prc_upd_gaji
( pi_no_peg
VARCHAR2) IS
v_pct_fgaji
NUMBER(5,2);
v_gaji_col
NUMBER;
BEGIN -- Penentuan nilai gaji yang digunakan -- untuk menentukan presentasi kenaikan gaji SELECT gaji INTO v_gaji_col FROM pegawai WHERE UPPER(no_peg) = UPPER(pi_no_peg); -- Menetapkan persentase kenaikan gaji IF v_gaji_col >= 3000000 THEN
v_pct_fgaji := 5.00; ELSIF v_gaji_col >= 2000000 THEN v_pct_fgaji := 8.00; ELSIF v_gaji_col >= 1000000 THEN v_pct_fgaji := 10.00; ELSE v_pct_fgaji := 15.00; END IF;
-- Update gaji, kenaikan gaji dibulatkan -- ke puluhan ribu terdekat UPDATE pegawai SET gaji = ROUND((1+v_pct_fgaji/100)*gaji, 4) WHERE no_peg = pi_no_peg;
SQL> exec prc_upd_gaji(‘PI-10001’);
Keterangan - IF v_gaji_col >= 3000000 THEN
v_pct_fgaji := 5.00; ELSIF v_gaji_col >= 2000000 THEN v_pct_fgaji := 8.00; ELSIF v_gaji_col >= 1000000 THEN v_pct_fgaji := 10.00; ELSE v_pct_fgaji := 15.00; END IF;
Jika gaji pegawai saat ini adalah p dan presentase kenaikan gaji yang baru adalah n, maka besarnya kenaikan gaji yang diperoleh adalah :
p ≥ 3.000.000 n = 0.05 2.000.000 ≤ p < 3.000.000 n = 0.08 1.000.000 ≤ p < 2.000.000 n = 0.10 p < 1.000.000 n = 0.15
- UPDATE pegawai SET gaji = ROUND((1+v_pct_fgaji/100)*gaji, 4) WHERE no_peg = pi_no_peg;
Berdasarkan besarnya nilai n yang diperoleh, jika gaji pegawai saat ini adalah p dan gaji yang baru adalah q, maka besarnya update gaji yang baru adalah : (kenaikan gaji dibulatkan ke puluhan ribu terdekat)
p ≥ 3.000.000 q = 1.05 p 2.000.000 ≤ p < 3.000.000 q = 1.08 p 1.000.000 ≤ p < 2.000.000 q = 1.10 p p < 1.000.000 q = 1.15 p
Lebih Lanjut Mengenai Prosedur 69
5.1.2 Statemen CASE
Struktur CASE ini sepadan dengan struktur IF-THEN-ELSIF. Pada penggunaan statemen CASE dapat diklasifikasikan ke dalam dua bagian, yaitu simple CASE dan searched CASE.
5.1.2.1 Simple CASE
CASE (ekspresi)
WHEN nilai_1 THEN statemen_1; WHEN nilai_2 THEN statemen_2;
... WHEN nilai_n THEN statemen_n;
[ELSE statemen_lain;] END CASE;
Struktur ini memiliki sebuah ekspresi setelah keyword CASE yang akan dibandingkan dengan tiap nilai pada blok WHEN. Kondisi WHEN yang pertama kali ditemukan bernilai TRUE akan dieksekusi dan dilanjutkan ke statemen di bawah blok pemilihan CASE.
Contoh
/*Prosedur untuk menentukan nama hari*/ CREATE OR REPLACE PROCEDURE prc_nama_hari
(pi_noHari
INTEGER) IS
v_namaHari
VARCHAR2;
BEGIN
-- Penentuan nama hari berdasar nomor urut hari v_namaHari :=
CASE pi_noHari WHEN 1 THEN ‘Senin’ WHEN 2 THEN ‘Selasa’ WHEN 3 THEN ‘Rabu’ WHEN 4 THEN ‘Kamis’ WHEN 5 THEN ‘Jumat’ WHEN 6 THEN ‘Sabtu’
WHEN 7 THEN ‘Minggu’ ELSE ‘Tidak terdefinisi’
END CASE; DBMS_OUTPUT.PUT_LINE(v_namaHari); END;
SQL> set serveroutput on SQL> exec prc_nama_hari(3);
Keterangan - v_namaHari :=
CASE pi_noHari WHEN 1 THEN ‘Senin’ WHEN 2 THEN ‘Selasa’ WHEN 3 THEN ‘Rabu’ WHEN 4 THEN ‘Kamis’ WHEN 5 THEN ‘Jumat’ WH EN 6 THEN ‘Sabtu’ WHEN 7 THEN ‘Minggu’ ELSE ‘Tidak terdefinisi’
END CASE;
Nilai variabel v_namaHari tergantung dari parameter input pi_noHari : noHari = 1 namaHari = Senin noHari = 2 namaHari = Selasa noHari = 3 namaHari = Rabu
noHari = 4 namaHari = Kamis noHari = 5 namaHari = Jumat noHari = 6 namaHari = Sabtu noHari = 7 namaHari = Minggu noHari ≠ 1,2,3,4,5,6, atau 7 namaHari = Tidak
terdefinisi
Lebih Lanjut Mengenai Prosedur 71
5.1.2.2 Searched CASE
CASE
WHEN ekspresi_1 = nilai_1 THEN statemen_1; WHEN ekspresi_2 = nilai_2 THEN statemen_2;
... WHEN ekspresi_n = nilai_n THEN statemen_n;
[ELSE statemen_lain;] END CASE;
Searched CASE mengevaluasi sederetan ekspresi untuk menemukan kondisi TRUE pertama. Kondisi WHEN pertama yang bernilai TRUE akan dieksekusi dan dilanjutkan ke statemen di bawah blok pemilihan CASE.
Contoh
/*Prosedur untuk menaikkan gaji pegawai*/ CREATE OR REPLACE PROCEDURE prc_upd_gaji
( pi_no_peg
VARCHAR2) IS
v_pct_fgaji
NUMBER(5,2);
v_gaji_col
NUMBER;
BEGIN -- Penentuan nilai gaji yang digunakan -- untuk menentukan presentasi kenaikan gaji SELECT gaji INTO v_gaji_col FROM pegawai WHERE UPPER(no_peg) = UPPER(pi_no_peg);
-- Menetapkan persentase kenaikan gaji CASE
WHEN v_gaji_col >= 3000000 THEN v_pct_fgaji := 5.00; WHEN v_gaji_col >= 2000000 THEN v_pct_fgaji := 8.00; WHEN v_gaji_col >= 1000000 THEN v_pct_fgaji := 10.00; ELSE v_pct_fgaji := 15.00; END CASE;
-- Update gaji, kenaikan gaji dibulatkan -- ke puluhan ribu terdekat UPDATE pegawai SET gaji = ROUND((1+v_pct_fgaji/100)*gaji, 4) WHERE no_peg = pi_no_peg;
SQL> exec prc_upd_gaji(‘PI-10001’);
Keterangan - CASE
WHEN v_gaji_col >= 3000000 THEN v_pct_fgaji := 5.00; WHEN v_gaji_col >= 2000000 THEN v_pct_fgaji := 8.00; WHEN v_gaji_col >= 1000000 THEN v_pct_fgaji := 10.00; ELSE v_pct_fgaji := 15.00; END CASE;
Jika gaji pegawai saat ini adalah p dan presentase kenaikan gaji yang baru adalah n, maka besarnya kenaikan gaji yang diperoleh adalah :
p ≥ 3.000.000 n = 0.05 2.000.000 ≤ p < 3.000.000 n = 0.08 1.000.000 ≤ p < 2.000.000 n = 0.10
p < 1.000.000 n = 0.15
Lebih Lanjut Mengenai Prosedur 73
Rangkuman
5. Percabangan (decision control / branching) adalah suatu kontrol untuk pengecekan yang dilakukan sebelum statemen-statemen dalam sebuah blok PL/SQL dieksekusi.
6. Klasifikasi decision control adalah : Statemen IF
o IF-THEN : pengecekan hanya untuk sebuah kondisi. IF kondisi THEN
statemen-statemen; END IF;
o IF-THEN-ELSE : pengecekan untuk dua kondisi. IF kondisi THEN
statemen-statemen A; ELSE statemen-statemen B; END IF;
o IF-THEN-ELSIF : pengecekan untuk tiga kondisi atau lebih.
IF kondisi_1 THEN
statemen-statemen A; ELSIF kondisi_2 THEN
statemen-statemen B; ... ELSIF kondisi_n THEN
statemen-statemen N; [ELSE statemen-statemen lain;] END IF;
Statemen CASE o Simple CASE
CASE (ekspresi)
WHEN nilai_1 THEN statemen_1; WHEN nilai_2 THEN statemen_2;
... WHEN nilai_n THEN statemen_n;
[ELSE statemen_lain;] END CASE;
o Searched CASE CASE
WHEN ekspresi_1 = nilai_1 THEN statemen_1; WHEN ekspresi_2 = nilai_2 THEN statemen_2;
... WHEN ekspresi_n = nilai_n THEN statemen_n;
[ELSE statemen_lain;] END CASE;
Lebih Lanjut Mengenai Prosedur 75
Kuis Benar Salah
11. Statemen dalam blok IF hanya akan dieksekusi bila kondisi IF terpenuhi.
12. Untuk pengecekan yang melibatkan lebih dari dua kondisi, penggunaan statemen IF-THEN-ELSIF atau CASE akan lebih efisien.
(Untuk soal nomor 3 – 5, perhatikan blok PL/SQL berikut) SET serveroutput ON;
DECLARE nilai INT; BEGIN nilai := 8; IF nilai > 0 THEN
DBMS_OUTPUT.PUT_LINE('Statemen IF 1st'); END IF; IF nilai < 10 THEN
DBMS_OUTPUT.PUT_LINE('Statemen IF 2nd'); END IF; END;
13. Output dari eksekusi blok PL/SQL di atas adalah : Statemen IF 2nd
14. Bila blok dalam BEGIN – END, diganti menjadi : nilai := 8;
IF nilai > 0 THEN DBMS_OUTPUT.PUT_LINE('Statemen IF 1st'); ELSIF nilai < 10 THEN DBMS_OUTPUT.PUT_LINE('Statemen IF 2nd'); END IF;
Maka output dari eksekusi blok PL/SQL di atas menjadi : Statemen IF 1st
15. Bila blok dalam BEGIN – END, diganti menjadi : nilai := 8;
IF nilai > 0 THEN DBMS_OUTPUT.PUT_LINE('Statemen IF 1st'); ELSE THEN DBMS_OUTPUT.PUT_LINE('Statemen IF 2nd'); END IF;
Maka output dari eksekusi blok PL/SQL di atas menjadi : Statemen IF 1st
16. Pada blok CASE, semua kondisi WHEN akan dicek sebelum akhirnya melanjutkan eksekusi statemen di bawah blok CASE tersebut.
(Untuk soal nomor 7 - 9, perhatikan blok PL/SQL berikut) SET serveroutput ON;
DECLARE nilai
BEGIN nilai := 60; CASE
WHEN nilai > 80.00 THEN indeks := ‘A’; WHEN nilai > 60 THEN indeks := ‘B’; WHEN nilai > 50 THEN indeks := ‘C’; ELSE indeks := ‘D’; END CASE; DBMS_OUTPUT.PUT_LINE(indeks);
END;
17. Output dari eksekusi blok PL/SQL di atas adalah :
Lebih Lanjut Mengenai Prosedur 77
18. Bila blok dalam BEGIN - END, diganti menjadi : nilai := 60;
CASE WHEN nilai >= 80.00 THEN indeks := ‘A’; WHEN nilai >= 60 THEN indeks := ‘B’; WHEN nilai >= 50 THEN indeks := ‘C’; ELSE indeks := ‘D’; END CASE; DBMS_OUTPUT.PUT_LINE(indeks);
Maka output dari eksekusi blok PL/SQL di atas menjadi :
19. Bila blok dalam BEGIN - END, diganti menjadi : nilai := 60;
CASE nilai WHEN >= 80.00 THEN indeks := ‘A’; WHEN >= 60 THEN indeks := ‘B’; WHEN >= 50 THEN indeks := ‘C’; ELSE indeks := ‘D’; END CASE; DBMS_OUTPUT.PUT_LINE(indeks);
Maka output dari eksekusi blok PL/SQL di atas menjadi :
20. Bila baris : ELSE
indeks := ‘D’; dihilangkan, maka akan terjadi error.
Latihan
Untuk soal nomor 1 – 3, perhatikan table employee_tab berikut :
emp_id mgr_id
dept_id
emp_name emp_salary
EM-10001 MG-10006 SAL
400 EM-10002 MG-10006 SAL
Sarah
400 EM-10003 MG-10007 HR
John
400 EM-10004 MG-10007 HR
Michael
400 EM-10005 MG-10006 SAL
George
400 MG-10006 NULL
Henk
800 MG-10007 NULL
o emp_id : id employee; mgr_id : id manager; dept_id : id department; emp_name : employee‘s name, emp_salary : employee‘s salary.
o emp_id dengan awalan ‖MG-‖ menyatakan bahwa ia adalah seorang manager dari department tertentu.
16. Buatlah sebuah prosedur untuk menghitung jumlah karyawan dalam department SAL :
o Jumlah karyawan akan dicetak ke layar. o Jika jumlah karyawan = 0 maka akan diberi keterangan ‖Department
belum berfungsi‖ ke layar. o Jika jumlah karyawan antara 1 – 10 maka akan diberi keterangan
‖Department kecil‖ ke layar. o Jika jumlah karyawan antara 11 – 20 maka akan diberi keterangan
‖Department menengah‖ ke layar. o Jika jumlah karyawan lebih dari 20 maka akan diberi keterangan
‖Department besar‖ ke layar. (Gunakan salah satu sintaks decision control yang paling efisien).
Lebih Lanjut Mengenai Prosedur 79
17. Buatlah sebuah fungsi untuk mengecek apakah karyawan dengan id tertentu adalah seorang manager atau bukan :
o Fungsi memiliki emp_id sebagai parameter input. o Fungsi akan mengembalikan TRUE bila emp_id yang dimasukkan
adalah milik seorang manager, dan FALSE bila sebaliknya. (Gunakan salah satu sintaks decision control yang paling efisien dan gunakan operator LIKE).
18. Buatlah sebuah blok PL/SQL (atau prosedur/fungsi) yang akan mengupdate salary dengan ketentuan :
o Jika seseorang adalah manager dari departemen apapun, maka akan mendapat kenaikan gaji sebesar 20% dari gaji semula.
o Jika seseorang adalah karyawan biasa di departemen SAL, maka akan mendapat kenaikan gaji sebesar 15% dari gaji semula.
o Jika seseorang adalah karyawan biasa di departemen HR, maka akan mendapat kenaikan gaji sebesar 10% dari gaji semula.
o Jika seseorang adalah karyawan biasa di departemen selain SAL dan HR, maka akan mendapat kenaikan gaji sebesar 5% dari gaji semula. (Gunakan HANYA satu buah decision control yang paling sesuai).
6 Lebih Lanjut Mengenai Prosedural
-Iterasi, Cursor, dan Exception Handling-
Overview
Pada sebuah blok PL/SQL dapat ditempatkan suatu kontrol untuk pengulangan eksekusi suatu blok statemen berdasarkan kondisi tertentu, penggunaan cursor secara implisit maupun eksplisit, dan menempatkan blok penanganan terhadap exception yang mungkin timbul.
Tujuan
1. Mahasiswa memahami konsep dan penggunaan perulangan (iterasi).
2. Mahasiswa memahami konsep dan penggunaan cursor.
3. Mahasiswa memahami konsep dan penggunaan exception handling.
Lebih Lanjut Mengenai Prosedur 81
6.1 Iterasi
Struktur iterasi (looping) memungkinkan eksekusi blok statemen secara berulang selama kondisi yang didefinisikan bernilai TRUE. Iterasi ini sendiri terbagi menjadi tiga jenis : simple loop (infinitif), FOR, dan WHILE.
Statemen EXIT atau EXIT WHEN dapat digunakan untuk keluar dari kontrol iterasi menuju statemen-statemen di bawah blok iterasi (setelah posisi END LOOP).
TRUE
FALSE
6.1.1 Simple LOOP
Struktur simple LOOP ini digunakan bila diinginkan minimal iterasi dijalankan satu kali. Dalam struktur ini harus ditambahkan statemen EXIT WHEN untuk menghindari eksekusi tak terbatas (infinitif).
LOOP statemen-statemen; END LOOP;
Contoh
/*Prosedur cetak baris*/ CREATE OR REPLACE PROCEDURE prc_ctk_baris
(n_akhir INTEGER)IS
-- Inisialisasi variabel pengecekan iterasi n_awal
INTEGER := 1;
BEGIN -- Pengecekan bila parameter input < 1 IF n_akhir < 1 THEN
DBMS_ OUTPUT.PUT_LINE(‘Nilai input minimal 1’); ELSE
-- Iterasi cetak baris sejumlah n_akhir LOOP
DBMS_ OUTPUT.PUT_LINE(‘Baris ke-’|| TO_CHAR(n_awal)); n_awal := n_awal + 1;
EXIT WHEN n_awal > n_akhir; END LOOP; END IF; END;
SQL> set serveroutput on; SQL> exec prc_ctk_baris(3);
Output :
Baris ke-1 Baris ke-2 Baris ke-3
6.1.2 Statemen FOR
Struktur ini tidak memiliki kondisi, sehingga perlu didefinisikan indeks minimal dan maksimal sebagai batas iterasi. Umumnya struktur ini digunakan untuk iterasi yang banyaknya sudah diketahui dengan pasti.
Lebih Lanjut Mengenai Prosedur 83
FOR var IN [REVERSE] indeks_min .. indeks_max LOOP statemen-statemen; END LOOP;
o Variabel iterasi (var) tidak perlu dideklarasi karena PL/SQL melakukan
deklarasi secara implisit dan variabel ini berlaku dalam LOOP itu saja. o Kata REVERSE akan membuat iterasi dimulai dari indeks_max dan berkurang satu untuk proses iterasi. Demikian seterusnya hingga var = indeks_min.
o Bila nilai indeks_max < indeks_min, proses iterasi tidak dilakukan.
Contoh - 1
/*Prosedur cetak angka secara increment*/ CREATE OR REPLACE PROCEDURE prc_cetak_inc
(n_akhir INTEGER)IS
BEGIN -- Pengecekan bila parameter input < 1 IF n_akhir < 1 THEN
DBMS_ OUTPUT.PUT_LINE(‘Nilai input minimal 1’); ELSE
-- Iterasi cetak angka sejumlah n_akhir FOR i IN 1 .. n_akhir LOOP
DBMS_OUTPUT.PUT(i); END LOOP; DBMS_OUTPUT.NEW_LINE; END IF; END;
Contoh - 2
/*Prosedur cetak angka secara decrement*/ CREATE OR REPLACE PROCEDURE prc_cetak_dec
(n_akhir INTEGER)IS
BEGIN -- Pengecekan bila parameter input < 1 IF n_akhir < 1 THEN
DBMS_ OUTPUT.PUT_LINE(‘Nilai input minimal 1’); ELSE
-- Iterasi cetak angka sejumlah n_akhir FOR i IN REVERSE 1 .. n_akhir LOOP
DBMS_OUTPUT.PUT(i); END LOOP; DBMS_OUTPUT.NEW_LINE; END IF; END;
SQL> set serveroutput on; SQL> exec prc_cetak_inc(5); SQL> exec prc_cetak_dec(5);
Output :
6.1.3 Statemen WHILE
Struktur ini selalu memeriksa kebenaran kondisi di awal blok iterasi. Bila kondisi bernilai FALSE, maka statemen-statemen dalam blok iterasi tidak akan dieksekusi.
WHILE kondisi LOOP statemen-statemen; END LOOP;
Contoh
/*Prosedur cetak baris*/ CREATE OR REPLACE PROCEDURE prc_ctk_baris
(n_akhir INTEGER)IS
-- Inisialisasi variabel pengecekan iterasi n_awal
INTEGER := 1;
Lebih Lanjut Mengenai Prosedur 85
BEGIN -- Pengecekan bila parameter input < 1 IF n_akhir < 1 THEN
DBMS_ OUTPUT.PUT_LINE(‘Nilai input minimal 1’); ELSE
-- Iterasi cetak baris sejumlah n_akhir WHILE n_awal < n_akhir LOOP
DBMS_ OUTPUT.PUT_LINE(‘Baris ke-’|| TO_CHAR(n_awal)); n_awal := n_awal + 1;
END LOOP; END IF; END;
SQL> set serveroutput on; SQL> exec prc_ctk_baris(3);
Output :
Baris ke-1 Baris ke-2 Baris ke-3
6.1.4 Statemen EXIT dan EXIT WHEN
Kedua statemen ini – EXIT dan EXIT WHEN – digunakan untuk keluar dari blok iterasi tanpa melanjutkan proses yang sedang dilakukan.
EXIT WHEN kondisi;
Perintah di atas identik dengan perintah berikut :
IF kondisi THEN EXIT; END IF;
6.2 Cursor
Blok PL/SQL tidak mengijinkan menampilkan beberapa baris dengan menggunakan perintah SELECT secara langsung. Untuk mengatasinya digunakanlah cursor. Cursor merupakan sejenis variabel yang dapat digunakan untuk menampung banyak nilai berupa baris atau record.
Dapat dikatakan pula cursor adalah pointer yang menunjuk ke suatu bagian memori untuk menyimpan hasil instruksi SQL. Hasil instruksi SQL tersebut biasanya merupakan multiple row, dan cursor digunakan untuk menunjuk (pointer) ke salah satu baris data.
Dalam penggunaannya, cursor harus melalui empat tahap : deklarasi (DECLARE), buka (OPEN), pengambilan data (FETCH), dan tutup (CLOSE).
Cursor sendiri dibedakan menjadi : cursor implisit dan cursor eksplisit.
6.2.1 Cursor Eksplisit
Cursor eksplisit merupakan cursor yang harus dibuka dan ditutup secara manual.
-- Deklarasi cursor DECLARE CURSOR nama_cursor IS statemen SELECT; -- Membuka cursor OPEN nama_cursor; -- Menangkap isi cursor
FETCH nama_cursor INTO nama_variabel; -- Menutup cursor CLOSE nama_cursor;
Contoh
/*Prosedur cetak data customer*/ CREATE OR REPLACE PROCEDURE prc_ctk_cust IS
-- Deklarasi cursor
Lebih Lanjut Mengenai Prosedur 87
CURSOR cur_customer IS
SELECT kode_cust, nama_cust from customer ORDER BY kode_cust;
-- Deklarasi variabel vRec cur_customer%ROWTYPE;
BEGIN -- Membuka cursor OPEN cur_customer;
-- Menangkap isi cursor LOOP
FETCH cur_customer INTO vRec; EXIT WHEN cur_customer%NOTFOUND; DBMS_OUTPUT.PUT_LINE(vRec.kode_cust|| ‘ ‘ ||
vRec.nama_cust); END LOOP;
-- Menutup cursor CLOSE cur_customer;
END;
Terdapat empat atribut yang dapat digunakan dalam pemrosesan cursor ini :
Atribut Deskripsi
%FOUND
Baris ditemukan
%NOTFOUND Baris tidak ditemukan %ROWCOUNT
Jumlah baris yang telah ditangkap melalui FETCH
%ISOPEN Bernilai TRUE bila cursor masih dalam keadaan terbuka
Contoh, bila ingin mengecek cursor dalam keadaan terbuka atau tidak :
IF nama_cursor%ISOPEN THEN statemen-statemen; END IF;
6.2.2 Cursor Implisit
Cursor eksplisit merupakan cursor yang tidak perlu dideklarasikan sebelumnya. Cursor ini berasosiasi dengan perintah SELECT, INSERT, DELETE, dan UPDATE.
Adapun atribut-atribut yang terdapat pada cursor ini adalah :
Atribut Deskripsi
Berasosiasi dengan SELECT, bernilai TRUE SQL%NOTFOUND bila query menghasilkan NULL dan FALSE bila query menghasilkan data
Kebalikan SQL%NOTFOUND, bernilai FALSE bila SQL%FOUND
query menghasilkan NULL dan TRUE bila query menghasilkan data
SQL%ISOPEN Bernilai TRUE saat eksekusi query, dan otomatis FALSE saat eksekusi selesai
SQL%ROWCOUNT Menunjukkan banyaknya baris yang dihasilkan dari sebuah query
/*Prosedur cari data customer*/ CREATE OR REPLACE PROCEDURE prc_src_cust
(pi_kode VARCHAR2) IS
-- Deklarasi variabel vNama customer.nama_cust%TYPE;
BEGIN -- Secara implisit mendeklarasikan, membuka, -- menangkap data, dan menutup cursor setelah -- cursor selesai diproses SELECT nama_cust INTO vNama FROM customer WHERE UPPER(kode_cust) = pi_kode;
-- Mengecek query memberikan hasil atau tidak IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE(‘Data Tidak Ditemukan’); ELSE
Lebih Lanjut Mengenai Prosedur 89
DBMS_OUTPUT.PUT_LINE(‘Nama customer : ’||vNama); END IF; END;
6.3 Menambahkan Exception Handling
Setiap kesalahan (error) atau peringatan (warning) yang muncul karena suatu perintah disebut sebagai exception. Blok EXCEPTION dapat ditempatkan dalam blok PL/SQL sebagai exception handler.
EXCEPTION
WHEN exception_1 [OR exception_2 [OR ...]] THEN
statemen-statemen; WHEN exception_a [OR exception_b [OR ...]] THEN
statemen-statemen; ... WHEN OTHERS THEN
statemen-statemen;
Sebaiknya hindari penggunaan exception OTHERS, karena exception ini tidak menangani exception yang sifatnya spesifik.
Terdapat tiga tipe exception, yaitu : Predefined exception, User defined exception, dan Non-predefined exception.
6.3.1 Predefined Exception
Oracle memiliki banyak jenis internal error dengan kode-kode tertentu. Kesalahan internal ini dibangkitkan secara otomatis tiap kali suatu perintah menimbulkan kondisi yang sesuai dengan jenis kesalahan tersebut. Beberapa jenis error yang umum dimasukkan ke dalam predefined exception agar dapat dilakukan penangan error tanpa mengetahui kode error-nya.
Beberapa predefined exception pada PL/SQL :
Error Kode Error Deskripsi
ORA-00001 DUP_VAL_ON_INDEX Input nilai duplikat pada kolom unik
ORA-00051 TIMEOUT_ON_RESOURCE Time out ORA-01001 INVALID_CURSOR
Operasi cursor ilegal ORA-01012 NOT_LOGGED_ON
Mengakses database tapi tidak terkoneksi
ORA-01017 LOGIN_DENIED Login dengan username atau password yang salah
ORA-01403 NO_DATA_FOUND Statemen SELECT INTO tidak menghasilkan baris data
Statemen SELECT INTO ORA-01422 TOO_MANY_ROWS
menghasilkan lebih dari satu baris data
ORA-01476 ZERO_DIVIDE Membagi dengan nol ORA-01722 INVALID_NUMBER
Gagal mengkonversi karakter ke number
Memori rusak atau proses ORA-06500 STORAGE_ERROR
membutuhkan memori lebih besar
ORA-06501 PROGRAM_ERROR Terjadi PL/SQL internal error
Kesalahan pada operasi aritmetika, konversi,
ORA-06502 VALUE_ERROR truncate, atau batasan rentang nilai
Dalam suatu penugasan, tipe ORA-06504 ROWTYPE_MISMATCH
data antara cursor variabel dengan PL/SQL cursor tidak cocok
ORA-06511 CURSOR_ALREADY_OPEN Membuka cursor yang sedang dibuka
Lebih Lanjut Mengenai Prosedur 91
Contoh
/*Prosedur cetak data karyawan*/ CREATE OR REPLACE PROCEDURE prc_ctk_karyawan
(pi_nama VARCHAR2)IS
vc_nama
VARCHAR2(40);
no_peg_col pegawai.no_peg%TYPE; gaji_col
pegawai.gaji%TYPE;
BEGIN -- Pengambilan data berdasar nama depan SELECT SUBSTR(nama_dpn||’ ‘||nama_blkng,1,40), no_peg, gaji INTO vc_nama, no_peg_col, gaji_col FROM pegawai WHERE UPPER(nama_dpn) LIKE ‘%’||UPPER(pi_nama)||’%’;
-- Cetak data karyawan DBMS_OUTPUT.PUT_LINE (‘Nama : ‘||vc_nama); DBMS_OUTPUT.PUT_LINE (‘NIP : ‘||no_peg_col); DBMS_OUTPUT.PUT_LINE (‘Gaji : ‘||gaji_col);
EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE (‘Data tidak ditemukan’); WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE (‘Lebih dari satu data ditemukan’); END;
SQL> set serveroutput on; SQL> exec prc_ctk_karyawan (‘robby’); SQL> exec prc_ctk_karyawan (‘ahmad’);
Output :
Data tidak ditemukan Lebih dari satu data ditemukan
6.3.2 User Defined Exception
User defined exception harus dideklarasikan manual oleh user layaknya variabel, hanya saja tipenya adalah EXCEPTION.
nama_exception EXCEPTION; Untuk membangkitkan exception jenis ini, digunakan perintah RAISE.
RAISE nama_exception;
Contoh
/*Prosedur update gaji karyawan*/ CREATE OR REPLACE PROCEDURE prc_upd_gaji
(pi_nopeg
VARCHAR2,
pi_gaji
INTEGER) IS
e_nopeg
EXCEPTION;
BEGIN -- Update gaji karyawan dengan NIP tertentu UPDATE pegawai SET gaji = pi_gaji WHERE no_peg = pi_nopeg;
-- Cek bila data tidak ditemukan IF SQL%NOTFOUND THEN
RAISE e_nopeg; END IF;
COMMIT;
EXCEPTION WHEN e_nopeg THEN DBMS_OUTPUT.PUT_LINE (‘Data tidak ditemukan’); END;
Lebih Lanjut Mengenai Prosedur 93
SQL> set serveroutput on; SQL> exec prc_upd_gaji (‘PI-10001’,2000000);
Output :
Data tidak ditemukan
Keterangan Untuk kasus ini, tidak bisa digunakan exception NO_DATA_FOUND karena
NO_DATA_FOUND hanya menangkap error akibat SELECT INTO saja.
6.3.3 Non-predefined Exception
Exception tipe ini sebenarnya termasuk user defined exception juga. Setelah dideklarasi, exception ini diasosiasikan ke sebuah error internal sehingga exception ini dibangkitkan secara otomatis.
nama_exception EXCEPTION;
PRAGMA EXCEPTION_INIT (nama_exception, nomor_error);
o Nomor error adalah bilangan integer negatif. o Kode errornya dalam format ―ORA-nnnnn‖ dengan ―nnnnn‖ adalah lima
angka absolut dari nomor error. o Contoh, kode error u ntuk nomor error ―-1‖ ―ORA-00001‖
Contoh
/*Prosedur input data karyawan*/ CREATE OR REPLACE PROCEDURE prc_ins_peg
(pi_nopeg
VARCHAR2,
pi_nama
VARCHAR2,
pi_pos_id
VARCHAR2,
pi_tgl_masuk DATE DEFAULT SYSDATE) IS
e_invalid_fk
EXCEPTION;
PRAGMA EXCEPTION_INIT(e_invalid_fk, -2291);
BEGIN -- Insert data karyawan baru INSERT INTO pegawai VALUES (pi_nopeg, INITCAP(pi_nama), pi_pos_id, pi_tgl_masuk);
COMMIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE (‘Duplikasi NIP’); WHEN e_invalid_fk THEN DBMS_OUTPUT.PUT_LINE (‘POS_ID tidak terdaftar’); END;
SQL> set serveroutput on; SQL> exec prc_ins_peg (‘PI-10001’, ‘Lia’, ‘PO-001’); SQL> exec prc_ins_peg (‘PI-10022’, ‘Edi’, ‘PO-022’);
Output :
Duplikasi NIP POS_ID tidak terdaftar
Keterangan Nomo r error ―-2291‖ disebabkan penggunaan nilai pada kolom foreign key
tidak terdapat pada kolom primary key dari tabel induknya.
6.3.4 Prosedur RAISE_APPLICATION_ERROR
RAISE_APPLICATION_ERROR adalah prosedur yang dapat digunakan untuk membuat dan membangkitkan exception. Dapat digunakan pada bagian executable statemen mapun exception handler.
RAISE_APPLICATION_ERROR(nomor_error, pesan_error [,TRUE|FALSE]);
Lebih Lanjut Mengenai Prosedur 95 Lebih Lanjut Mengenai Prosedur 95
o pesan_error adalah pesan kesalahan yang ingin dimunculkan. o TRUE|FALSE adalah parameter optional, dengan nilai default FALSE.
TRUE bertujuan untuk menangkap exception-exception sebelumnya bersama exception ini. FALSE bertujuan menggantikan exception terdahulu dengan exception ini.
Contoh - 1
/*Prosedur update gaji karyawan dengan exception handling pada bagian executable statemen*/ CREATE OR REPLACE PROCEDURE prc_upd_gaji
(pi_nopeg
VARCHAR2,
pi_gaji
INTEGER) IS
BEGIN -- Update gaji karyawan dengan NIP tertentu UPDATE pegawai SET gaji = pi_gaji WHERE no_peg = pi_nopeg;
-- Cek bila data tidak ditemukan IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(- 20100, ‘Data tidak ditemukan’); END IF; COMMIT; END;
Contoh - 2
/*Prosedur input data karyawan*/ CREATE OR REPLACE PROCEDURE prc_ins_peg
(pi_nopeg
VARCHAR2,
pi_nama
VARCHAR2,
pi_tgl_masuk DATE DEFAULT SYSDATE) IS
BEGIN -- Insert data karyawan baru INSERT INTO pegawai VALUES (pi_nopeg, INITCAP(pi_nama), pi_tgl_masuk);
COMMIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN RAISE_APPLICATION_ERROR(- 20101, ‘Duplikasi NIP’); END;
SQL> set serveroutput on; SQL> exec prc_upd_gaji (‘PI-10001’,2000000); SQL> exec prc_ins_peg (‘PI-10001’, ‘Lia’);
Output :
Data tidak ditemukan Duplikasi NIP
Keterangan Contoh-1 merupakan contoh penggunaan RAISE_APPLICATION_ERROR
pada bagian executable statemen dan Contoh-2 adalah contoh penggunaan pada exception handler.
Lebih Lanjut Mengenai Prosedur 97
Rangkuman
7. Iterasi digunakan untuk mengeksekusi blok statemen secara berulang berdasar kondisi tertentu.
8. Jenis-jenis iterasi : o Simple LOOP : minimal iterasi dijalankan satu kali. Harus
ditambahkan statemen EXIT WHEN untuk menghindari eksekusi tak terbatas (infinitif).
LOOP statemen-statemen; END LOOP;
o Statemen FOR : tidak memiliki kondisi, perlu didefinisikan indeks minimal dan maksimal sebagai batas iterasi.
FOR var IN [REVERSE] indeks_min .. indeks_max LOOP
statemen-statemen; END LOOP;
o Struktur ini selalu memeriksa kebenaran kondisi di awal blok iterasi. Bila kondisi bernilai FALSE, maka statemen-statemen dalam blok iterasi tidak akan dieksekusi.
WHILE kondisi LOOP statemen-statemen; END LOOP;
9. EXIT dan EXIT WHEN : digunakan untuk keluar dari blok iterasi tanpa melanjutkan proses yang sedang dilakukan.
EXIT WHEN kondisi;
IF kondisi THEN EXIT; END IF;
10. Cursor adalah pointer yang menunjuk ke suatu bagian memori untuk menyimpan hasil instruksi SQL (biasanya merupakan multiple row) dan cursor digunakan untuk menunjuk (pointer) ke salah satu baris data.
11. Empat tahap dalam menggunakan cursor : o deklarasi cursor (DECLARE)
o membuka cursor (OPEN) o pengambilan data ke dalam cursor (FETCH) o menutup cursor (CLOSE)
12. Jenis-jenis cursor : o Eksplisit cursor : harus dibuka dan ditutup secara manual.
-- Deklarasi cursor DECLARE CURSOR nama_cursor IS statemen SELECT; -- Membuka cursor OPEN nama_cursor; -- Menangkap isi cursor FETCH nama_cursor INTO nama_variabel; -- Menutup cursor CLOSE nama_cursor;
o Implisit cursor : cursor yang tidak perlu dideklarasikan sebelumnya. Cursor ini berasosiasi dengan perintah SELECT, INSERT, DELETE, dan UPDATE
Lebih Lanjut Mengenai Prosedur 99
13. Exception handling adalah cara mengatasi setiap kesalahan (error) atau peringatan (warning) yang muncul karena suatu perintah dengan menempatkan blok exception handler:
14. Jenis-jenis exception : o Predefned exception : kesalahan internal yang dibangkitkan secara
otomatis tiap kali suatu perintah menimbulkan kondisi yang sesuai dengan jenis kesalahan tersebut.
o User defined exception : harus dideklarasikan manual oleh user layaknya variabel.
nama_exception EXCEPTION; Untuk membangkitkan exception ini :
RAISE nama_exception; o Non-predefined exception : setelah dideklarasi, exception ini
diasosiasikan ke sebuah error internal sehingga exception ini dibangkitkan secara otomatis.
nama_exception EXCEPTION; PRAGMA EXCEPTION_INIT (nama_exception, nomor_error);
15. RAISE_APPLICATION_ERROR adalah prosedur yang disediakan untuk membuat dan membangkitkan exception. Dapat digunakan pada bagian executable statemen mapun exception handler.
RAISE_APPLICATION_ERROR(nomor_error, pesan_error [,TRUE|FALSE]);
Kuis Benar Salah
1. Statemen WHILE akan selalu mengecek kondisi sebelum statemen dalam blok iterasi dilakukan.
2. Statemen EXIT dan EXIT WHEN hanya dapat digunakan pada Simple LOOP.
(Untuk soal 3 – 4, perhatikan blok PL/SQL berikut) SET serveroutput ON;
DECLARE v_awal
INTEGER := 1;
v_akhir
INTEGER := 0;
BEGIN LOOP
DBMS_OUTPUT.PUT_LINE('Baris ke-'|| TO_CHAR(v_awal)); v_awal := v_awal + 1; EXIT WHEN v_awal > v_akhir;
END LOOP; DBMS_OUTPUT.NEW_LINE; END;
3. Tidak ada output apapun yang akan ditampilkan ke layar.
4. Jika blok BEGIN – END diganti menjadi : LOOP
EXIT WHEN v_awal > v_akhir; DBMS_OUTPUT.PUT_LINE('Baris ke-'|| TO_CHAR(v_awal)); v_awal := v_awal + 1;
END LOOP; DBMS_OUTPUT.NEW_LINE;
Lebih Lanjut Mengenai Prosedur 101
Tidak akan ada output apapun yang akan ditampilkan ke layar.
(Untuk soal 5 - 6, perhatikan blok PL/SQL berikut)
SET serveroutput ON; DECLARE
n_akhir
INTEGER := 5;
BEGIN FOR i IN 1 .. n_akhir LOOP DBMS_OUTPUT.PUT(i); EXIT WHEN i > 3;
END LOOP; DBMS_OUTPUT.NEW_LINE; END;
5. Output dari blok PL/SQL di atas adalah : 12345
6. Jika blok FOR LOOP diganti menjadi : FOR i IN 1 .. n_akhir LOOP
DBMS_OUTPUT.PUT(i); EXIT;
END LOOP; Maka outputnya adalah : 12345
7. Perbedaan antara cursor implisit dan eksplisit adalah pada proses pembukaan dan penutupan cursor tersebut.
(Untuk soal 8 – 9, perhatikan blok PL/SQL berikut)
SET serveroutput ON; DECLARE
CURSOR cur_customer IS SELECT cust_id, cust_name FROM customer WHERE UPPER(cust_name) LIKE UPPER('%eni%') ORDER BY cust_id; v_Rec cur_customer%ROWTYPE; v_Row INTEGER := 0;
BEGIN
OPEN cur_customer;
WHILE cur_customer%FOUND LOOP FETCH cur_customer INTO vRec; END LOOP;
v_Row := cur_customer%rowcount; DBMS_OUTPUT.PUT_LINE( ‘Jumlah row = ’||v_Row);
CLOSE cur_customer; END;
8. Jika output query : SELECT count(cust_id) FROM customer
WHERE UPPER(cust_name) LIKE UPPER('%eni%') ORDER BY cust_id;
adalah :
8 Maka output dari blok PL/SQL di atas adalah :
Jumlah row = 8
Lebih Lanjut Mengenai Prosedur 103
9. Jika blok BEGIN – END diganti menjadi : OPEN cur_customer;
FETCH cur_customer INTO vRec;
WHILE cur_customer%FOUND LOOP FETCH cur_customer INTO vRec; END LOOP;
v_Row := cur_customer%rowcount; DBMS_OUTPUT.PUT_LINE( ‘Jumlah row = ’||v_Row);
CLOSE cur_customer; Maka output dari blok PL/SQL di atas menjadi : Jumlah row = 7
10. Dengan prosedur RAISE_APPLICATION_ERROR, tidak perlu
menggunakan statemen RAISE untuk membangkitkan sebuah exception.
Latihan
1. Sebutkan jenis-jenis statemen iterasi beserta perbedaan masing-masing.
2. Sebutkan jenis-jenis cursor beserta perbedaan masing-masing.
3. Sebutkan jenis-jenis exception beserta perbedaan masing-masing.
4. Buatlah sebuah prosedur untuk mencetak sejumlah bilangan prima pertama berdasar parameter input dengan menggunakan simple LOOP.
Contoh : Input = 5 Output : 2 3 5 Input = 15 Output : 2 3 5 7 11 13
5. Buatlah sebuah fungsi yang akan mengembalikan nilai faktorial dari sebuah parameter input.
Rumus faktorial : n! = n x (n-1) Contoh : Input = 3 Output : 6 (didapat dari : 3! = 3x2x1 = 6) Input = 5 Output : 120 (didapat dari : 5! = 5x4x3x2x1 = 120)
(Untuk soal nomor 6 – 7, perhatikan table berikut)
emp_id mgr_id
dept_id
emp_name emp_salary
EM-10001 MG-10006 SAL
410 EM-10002 MG-10006 SAL
Sarah
360 EM-10003 MG-10007 HR
John
430 EM-10004 MG-10007 HR
Michael
320 EM-10005 MG-10006 SAL
George
400 MG-10006 NULL
Henk
810 MG-10007 NULL
Lebih Lanjut Mengenai Prosedur 105
6. Buatlah sebuah blok PL/SQL untuk menampilkan 5 employee dengan gaji tertinggi. Data yang ditampilkan meliputi : emp_id, emp_name, dan emp_salary. (Gunakan eksplisit cursor dan statemen WHILE).
7. Buatlah sebuah fungsi yang akan mengembalikan nama manager dari emp_id yang dimasukkan.
Contoh : Input = EM-10001 Output : Natalie (Gunakan implisit kursor dan salah satu exception handling apabila emp_id yang dimasukkan tidak ditemukan di table).
7 Tingkat Lanjut Konsep Prosedural
-Index, Prosedur, Fungsi-
Overview
Untuk meningkatkan performansi saat dilakukan query terhadap suatu tabel maka bisa dibuatkan index terhadap tabel tersebut dengan aturan tertentu.
Untuk membuat kode PL/SQL lebih bersifat modular dan lebih mudah di- maintain, maka dapat digunakan prosedur dan fungsi yang melakukan tujuan spesifik.
Tujuan
1. Mahasiswa memahami konsep dan penggunaan index.
2. Mahasiswa memahami konsep dan penggunaan prosedur.
3. Mahasiswa memahami konsep dan penggunaan fungsi.
Tingkat Lanjut Konsep Prosedural 107
7.1 Index
Index adalah objek database yang dapat dibuat untuk meningkatkan performansi dari query. Index juga dapat dibuat secara otomatis oleh server saat dibuat primary key atau unique constraint.
7.1.1 Membuat Index
Index dapat dibuat dengan dua cara : secara otomatis saat primary key atau unique constraint dibuat dan secara manual menggunakan statemen CREATE INDEX.
7.1.1.1 Membuat Index Secara Otomatis
Saat pembuatan tabel dengan primary key, akan dibuat index untuk tabel tersebut secara otomatis. Nama index akan dibuat sama dengan nama constraint primary key-nya.
Informasi index-index yang sudah ada dapat dilihat pada data dictionary, yaitu melalui view ALL_INDEXES, DBA_INDEXES, dan USER_INDEXES.
Contoh
/*Membuat tabel dengan primary key*/ CREATE TABLE pegawai ( no_peg
VARCHAR2(8) NOT NULL, nama_dpn
VARCHAR2(20) NOT NULL, nama_blkg
VARCHAR2(20),
pos_id VARCHAR2(8) NOT NULL, gaji
NUMBER(8),
CONSTRAINT pk_pegawai PRIMARY KEY(no_peg) );
SQL> SELECT table_name, index_name, uniqueness,
2 status
3 FROM USER_INDEXES;
Output :
TABLE_NAME INDEX_NAME UNIQUENESS STATUS -------------- -------------- -------------- ------ PEGAWAI
PK_PEGAWAI UNIQUE VALID
7.1.1.2 Membuat Index Secara Manual
CREATE INDEX [schema.]index
ON [schema.]tabel ({kolom [ASC|DSC]});
o Index dapat dibuat oleh user pemilik schema atau user lain yang memiliki system priviledge CREATE ANY INDEX atau yang mempunyai object priviledge INDEX atas tabel tersebut.
o Apabila sebuah kolom atau kombinasi kolom sudah di-index, akan muncul pesan kesalahan saat dibuat index lain terhadap kolom tersebut.
Contoh
/*Membuat index terhadap tabel*/ CREATE INDEX idx_pos_gaji ON pegawai(pos_id, gaji);
SQL> SELECT table_name, index_name, uniqueness,
2 status
3 FROM USER_INDEXES;
Output :
TABLE_NAME INDEX_NAME UNIQUENESS STATUS -------------- -------------- -------------- ------ PEGAWAI
PK_PEGAWAI UNIQUE VALID PEGAWAI
IDX_POS_GAJI NONUNIQUE VALID
Tingkat Lanjut Konsep Prosedural 109
7.1.1.3 Acuan Membuat Index
Meskipun index bertujuan untuk mempercepat akses data, tapi bukan berarti semakin banyak index maka semakin cepat pula akses terhadap data. Index harus di-update tiap kali operasi DML terhadap tabel tersebut di- commit. Oleh karenanya, makin banyak index maka makin banyak pula pekerjaan yang harus dilakukan oleh server.
Buat index saat :
Sebuah kolom memiliki rentang nilai yang besar Sebuah kolom memiliki banyak nilai NULL Satu atau lebih kolom sering digunakan bersama pada klausa WHERE atau kondisi JOIN
Tabel berukuran besar dan kebanyakan query yang dilakukan terhadapnya menghasilkan kurang dari 2% - 4% row dari tabel
Jangan buat index saat :
Sebuah kolom jarang digunakan sebagai kondisi pada query Tabel berukuran kecil dan kebanyakan query yang
dilakukan terhadapnya menghasilkan lebih dari 2% - 4% row dari tabel
Tabel sering di-update Kolom yang akan di-index direferensi sebagai bagian dari suatu ekspresi
7.1.2 Mengganti Nama Index
ALTER INDEX [schema.]index RENAME TO index_baru;
Contoh
/*Mengganti nama index*/ ALTER INDEX idx_pos_gaji RENAME TO idx_posisi_gaji;
7.1.3 Menghapus Index
DROP INDEX [schema.]index;
Contoh
/*Menghapus index*/ DROP INDEX idx_pos_gaji;
7.2 Callable Procedure & Function
Prosedur dan fungsi adalah blok PL/SQL yang berdiri sendiri dan disimpan sebagai objek database untuk melakukan tugas spesifik. Kedua objek ini hanya perlu dibuat sekali dan dapat dipanggil sewaktu-waktu untuk tujuan yang sama
7.2.1 Prosedur
Prosedur adalah blok PL/SQL yang menyimpan sekumpulan perintah tanpa disertai pengembalian nilai.
7.2.1.1 Membuat Prosedur
CREATE [OR REPLACE] PROCEDURE nama_prosedur (parameter1 tipedata, parameter2 tipedata,...) IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ...
END;
Tingkat Lanjut Konsep Prosedural 111
Contoh
/*Prosedur pengecekan stok lemari es*/ CREATE OR REPLACE PROCEDURE prc_stok_brg IS
vstok INTEGER; BEGIN
-- Mengambil nilai stok dari barang lemari es -- (nilai stok adalah bilangan positif) SELECT stok_barang INTO vstok FROM barang WHERE UPPER(nama_barang) = UPPER(‘lemari es’);
--Memeriksa nilai dari variabel vstok IF vstok = 0 THEN
--Jika vstok = 0, cetak keterangan ke layar DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’);
END IF; END;
7.2.1.2 Eksekusi Prosedur
EXE[CUTE] nama_prosedur(daftar_parameter); o Bila prosedur dieksekusi dalam blok PL/SQL, maka statemen EXECUTE
tidak perlu dituliskan.
Contoh
SQL> set serveroutput on; SQL> exec prc_stok_brg;
Keterangan - SET SERVEROUTPUT ON untuk mengaktifkan variabel SERVEROUTPUT
agar DBMS_OUTPUT.PUT_LINE dapat dieksekusi.
7.2.2 Fungsi
Fungsi adalah blok PL/SQL yang dapat mengembalikan nilai. Karena itu perlu ditambahkan statemen RETURN untuk proses pengembalian nilai.
7.2.2.1 Membuat Fungsi
CREATE [OR REPLACE] FUNCTION nama_fungsi (parameter1 tipedata, parameter2 tipedata,...) RETURN tipe_data_fungsi IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ... RETURN nilai_fungsi;
END;
Contoh
/*Fungsi pencarian nama supplier*/ CREATE OR REPLACE FUNCTION cari_supp
(pi_kode VARCHAR2) RETURN supplier.nama_supp%TYPE IS
vNamaSupp supplier.nama_supp%TYPE;
BEGIN
-- Mengambil nama supplier berdasar parameter SELECT nama_supp INTO vNamaSupp FROM supplier WHERE UPPER(kode_supp) = UPPER(pi_kode);
-- Mengembalikan nilai RETURN vNamaSupp;
END;
Tingkat Lanjut Konsep Prosedural 113
7.2.2.2 Pemanggilan Fungsi
Berbeda dengan prosedur yang memerlukan statemen EXECUTE, fungsi dapat langsung dimasukkan nilainya ke dalam variabel yang bertipe sama dengan tipe nilai balikannya.
Contoh
/*Pemanggilan fungsi*/ DECLARE
nama supplier.nama_supp%TYPE;
BEGIN -- Memasukkan nilai fungsi ke variabel nama nama := cari_supp(‘SU-10001’);
-- Mencetak nilai variabel nama ke layar DBMS_OUTPUT.PUT_LINE (nama);
END;
Fungsi dapat pula dipanggil dengan statemen SELECT.
Contoh
/*Pemanggilan fungsi*/ SELECT cari_supp(‘SU-10001’) from DUAL;
7.2.3 Parameter
Parameter adalah nilai yang dilewatkan dalam sebuah prosedur atau fungsi. Ada tiga jenis parameter : parameter input, output, dan input-output.
7.2.3.1 Parameter Input
Parameter input berguna untuk menyimpan nilai yang akan digunakan sebagai input pada badan prosedur maupun fungsi. Parameter ini ditandai dengan mode IN, tapi bila mode ini dihilangkan maka secara otomatis akan dianggap sebagai parameter input juga.
Contoh
/*Prosedur pengecekan stok barang*/ CREATE OR REPLACE PROCEDURE prc_stok_brg
(pi_brg VARCHAR2) IS
vstok INTEGER;
BEGIN -- Mengambil nilai stok dari barang -- (nilai stok adalah bilangan positif) SELECT stok_barang INTO vstok FROM barang WHERE UPPER(nama_barang) = UPPER(pi_brg);
--Memeriksa nilai dari variabel vstok IF vstok = 0 THEN
--Jika vstok = 0, cetak keterangan ke layar DBMS_ OUTPUT.PUT_LINE(‘Persediaan barang telah habis’);
END IF; END;
SQL> set serveroutput on; SQL> exec prc_stok_brg (‘lemari es’);
Tingkat Lanjut Konsep Prosedural 115
7.2.3.2 Parameter Output
Parameter output berperan untuk menampung nilai hasil dari suatu proses yang dilakukan di dalam prosedur atau fungsi. Pada kenyataannya, parameter ini lebih sering ditemukan pada prosedur. Parameter output ditandai dengan mode OUT
Contoh
/*Prosedur pencarian nama supplier*/ CREATE OR REPLACE PROCEDURE cari_supp
( pi_kode IN VARCHAR2, vNamaSupp OUT supplier.nama_supp%TYPE) IS BEGIN
-- Mengambil nama supplier berdasar parameter SELECT nama_supp INTO vNamaSupp FROM supplier WHERE UPPER(kode_supp) = UPPER(pi_kode);
END;
Contoh blok PL/SQL yang mengeksekusi prosedur di atas : /*Blok yang mengeksekusi prosedur*/
DECLARE nama
supplier.nama_supp%TYPE;
BEGIN -- Eksekusi prosedur cari_supp(‘SU-10001’, nama);
-- Mencetak nilai variabel nama ke layar DBMS_OUTPUT.PUT_LINE (nama);
END;
7.2.3.3 Parameter Input-Output
Parameter ini merupakan gabungan dari kedua parameter sebelumnya. Mula-mula badan prosedur atau fungsi akan melakukan proses terhadap nilai input yang dikirimkan oleh parameter ini, kemudian nilai hasil dari proses tersebut akan dimasukkan kembali ke parameter ini.
Suatu parameter dikatakan sebagai paramter input-output bila dituliskan dalam mode IN OUT.
Contoh
/*Prosedur pencarian nama supplier*/ CREATE OR REPLACE PROCEDURE cari_supp
( vParam IN OUT VARCHAR2) IS
vHasil supplier.nama_supp%TYPE;
BEGIN
-- Mengambil nama supplier berdasar parameter SELECT nama_supp INTO vHasil FROM supplier WHERE UPPER(kode_supp) = UPPER(vParam);
-- Memasukkan nilai hasil ke parameter vParam := vHasil;
END;
Contoh blok PL/SQL yang mengeksekusi prosedur di atas : /*Blok yang mengeksekusi prosedur*/
DECLARE vLokal VARCHAR2 := ‘SU-10001’;
BEGIN -- Mencetak nilai parameter input DBMS_OUTPUT.PUT_LINE (vLokal);
-- Eksekusi prosedur cari_supp(vLokal);
Tingkat Lanjut Konsep Prosedural 117
-- Mencetak nilai parameter output DBMS_OUTPUT.PUT_LINE (vLokal);
END;
Rangkuman
16. Index adalah objek database yang dapat dibuat untuk meningkatkan performansi dari query.
17. Index dapat dibuat dengan cara : Otomatis : dibuat secara otomatis oleh server saat pembuatan tabel
dengan primary key atau unique constraint. Manual : dibuat secara manual dengan statemen CREATE INDEX.
CREATE INDEX [schema.]index ON [schema.]tabel ({kolom [ASC|DSC]});
18. Manipulasi terhadap index : Mengganti nama index
ALTER INDEX [schema.]index RENAME TO index_baru;
Menghapus index DROP INDEX [schema.]index;
19. Prosedur adalah blok PL/SQL yang menyimpan sekumpulan perintah tanpa disertai pengembalian nilai.
CREATE [OR REPLACE] PROCEDURE nama_prosedur (parameter1 tipedata, parameter2 tipedata,...) IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ...
END;
Tingkat Lanjut Konsep Prosedural 119
20. Fungsi adalah blok PL/SQL yang dapat mengembalikan nilai. Karena itu perlu ditambahkan statemen RETURN untuk proses pengembalian nilai.
CREATE [OR REPLACE] FUNCTION nama_fungsi (parameter1 tipedata, parameter2 tipedata,...) RETURN tipe_data_fungsi IS variable_variabel_lokal tipedata; BEGIN statemen_statemen; ... RETURN nilai_fungsi;
END;
21. Parameter adalah nilai yang dilewatkan dalam sebuah prosedur atau fungsi. Ada tiga jenis parameter : parameter input, output, dan input- output.
Parameter input : menyimpan nilai yang akan digunakan sebagai input pada badan prosedur maupun fungsi. Ditandai dengan mode IN.
Parameter output : menampung nilai hasil dari suatu proses yang dilakukan di dalam prosedur atau fungsi. Ditandai dengan mode
OUT. Parameter input-output : berfungsi sebagai parameter input maupun output. Ditandai dengan mode IN OUT.
Studi Kasus : Pembuatan Laporan
Pada studi ini, kasus inventory akan digunakan sebagai contoh dalam penerapan index, prosedur, maupun fungsi.
1. Buat 3 buah table dengan spesifikasi sebagai berikut : o supplier
CREATE TABLE SUPPLIER ( SUPP_ID VARCHAR2(8) NOT NULL, SUPP_NAME VARCHAR2(50) NOT NULL, SUPP_ADDR VARCHAR2(120) CONSTRAINT PK_SUPPLIER PRIMARY KEY(SUPP_ID) );
o barang CREATE TABLE BARANG (
BRG_ID VARCHAR2(8) NOT NULL, BRG_NAME VARCHAR2(50) NOT NULL, BRG_STOK INTEGER DEFAULT 0, CONSTRAINT PK_BARANG PRIMARY KEY(BRG_ID) );
o pasok CREATE TABLE PASOK (
PAS_ID VARCHAR2(8) NOT NULL, PAS_DATE DATE DEFAULT SYSDATE, PAS_SUPP VARCHAR2(8), PAS_BRG VARCHAR2(8), PAS_AMT INTEGER DEFAULT 0, CONSTRAINT PK_PASOK PRIMARY KEY(PAS_ID), CONSTRAINT FK_PASOK_SUPPLIER FOREIGN KEY(PAS_SUPP) REFERENCES SUPPLIER(SUPP_ID),
Tingkat Lanjut Konsep Prosedural 121
CONSTRAINT FK_PASOK_BARANG FOREIGN KEY(PAS_BRG) REFERENCES BARANG(BRG_ID)
2. Buatlah sebuah nonunique index untuk field PAS_DATE pada tabel PASOK.
3. Insert data pada ketiga tabel tersebut : o supplier
SUPP_ID
SUPP_NAME
SUPP_ADDR
SP-10001 CV. KARYA Jl. Pembangunan, Jakarta SP-10002 PT. MAJU
Jl. Diponegoro, Yogyakarta
SP-10003 CV. MURAH Jl. Harapan, Bandung ...
(Bila perlu, tambahkan data lainnya). o barang
BRG_ID
BRG_NAME
BRG_STOK
BR-10001 Lemari pakaian 15 BR-10002 Meja belajar
17 BR-10003 Kasur
(Bila perlu, tambahkan data lainnya). o pasok
PAS_ID
PAS_DATE
PAS_SUPP PAS_BRG PAS_AMT
PS-10001 08/07/2008 SP-10001 BR-10001 5 PS-10002 08/07/2008
SP-10001 BR-10002 7 PS-10003 08/11/2008
SP-10002 BR-10003 12 PS-10004 08/12/2008
SP-10003 BR-10002 3 PS-10005 08/12/2008
SP-10003 BR-10003 10 ...
(Bila perlu, tambahkan data lainnya).
4. Buatlah sebuah fungsi untuk mengecek stok suatu jenis barang : o Parameter input adalah id barang.
o Akan mengembalikan TRUE bila stok barang tidak nol, dan FALSE bila stok sama dengan nol.
5. Buatlah sebuah prosedur yang akan mencetak laporan pasok berdasar supplier tertentu :
o Parameter input adalah id supplier. o Bentuk laporan :
Nama Supplier : _______________ Alamat
Tgl Pasok
Nama Barang
Jumlah Pasok
o Contoh pemanggilan prosedur : EXEC nama_prosedur (‗SP-10001‘);
6. Buatlah sebuah prosedur yang akan mencetak laporan pasok berdasar bulan dan tahun tertentu :
o Parameter input adalah bulan dan tahun pasok. o Bentuk laporan :
Bulan : __________ *
Tahun : __________
Nama Supplier
Nama Barang
Jumlah Pasok
o Contoh pemanggilan prosedur : EXEC nama_prosedur (‗08‘, ‗2008‘); * Bulan ditampilkan dalam format Januari...Desember, untuk
itu perlu ditambahkan fungsi pendukung untuk mengkonversi format bulan dari ‘08’ menjadi Januari...Desember.
Tingkat Lanjut Konsep Prosedural 123
8 DATABASE-TRIGGER
Overview
Apabila kita menginginkan suatu aksi yang dapat memicu terjadinya aksi atau perubahan yang lain pada data yang kita miliki. Kita dapat menggunakan trigger. Trigger akan memicu sebuah aksi terjadi pada sebuah data atau memicu untuk membangkitkan trigger yang lain.
Tujuan
1. Mahasiswa Praktikan memahami trigger.
2. Mahasiswa mengerti fungsi dan kelebihan penggunaan trigger.
3. Mahasiswa mampu mengimplementasikan trigger
8.1 Definisi Trigger
Trigger adalah blok PL/SQL yang disimpan dalam database dan dijalankan secara implisit sebagai respon terhadap perubahan yang telah ditentukan dalam database. Perintah DML seperti INSERT, UPDATE, dan DELETE adalah pemicu umum terjadinya trigger. Operasi DDL seperti ALTER dan DROP juga dapat memicu dijalankannya trigger.
8.2 Fungsi dan Kelebihan
Fungsi dan kelebihan penggunaan trigger antara lain: Memperbaiki integritas data dengan membuat integrity constraint yang kompleks yang mana tidak mungkin ditangani oleh sintaks pembutan tabel (lihat modul 1).
Memvalidasi transaksi data. Memperbaiki keamanan database dengan menyediakan audit yang
lebih kompleks mengenai informasi perubahan database dan user siapa yang melakukan perubahan.
8.3 Aplikasi yang dapat dilakukan oleh Trigger diantaranya adalah :
Membuat isi dari kolom yang diambil dari kolom lain. Membuat mekanisme validasi yang mencakup query pada banyak
tabel. Membuat log untuk mendaftarkan penggunaan table. Mengupdate tabel – tabel lain apabila ada penambahan atau
perubahan lain di dalam tabel yang sedang aktif.
Query Optimization 125
8.4 SINTAKS
CREATE [OR REPLACE] TRIGGER [user.]nama_trigger {BEFORE | AFTER | INSTEAD OF} {DELETE | INSERT | UPDATE [OF nama_kolom [, nama_kolom] ...]}
[OR {DELETE | INSERT | UPDATE [OF column [, column] ...]}]...
ON [user.]{nama_tabel | nama_view} [{REFERENCING {OLD [AS] old_value | NEW [AS] new_value} ...] FOR EACH {ROW | STATEMENT} [WHEN (condition)]
PL/SQL_BLOCK Nama trigger sebaiknya dengan jelas mencerminkan tabel yang
diaplikasikan. Perintah DML trigger, status before/after, dan apakah row level atau statement level.
Bagian
Keterangan
Nilai yang mungkin
BEFORE
ketika trigger berelasi
trigger timing AFTER
ke event
INSTEAD OF
manipulasi data pada
INSERT
tebel/ view yang
trigger event UPDATE
menyebabkan trigger
DELETE
terpacu berapa kali body
ROW trigger type
STATEMENT trigger body
trigger dieksekusi
apa action dari trigger
Block PL/SQL lengkap
misalnya trigger BEFORE UPDATE dengan row level pada tabel KARYAWAN dapat diberi nama bef_upd_row_karyawan.
8.5 TIPE TRIGGER
a. Row-level and Statement-level Trigger
Row-level and Statement-level trigger merupakan pembagian trigger berdasarkan jumlah aksinya.
Row-level trigger dieksekusi untuk setiap row yang dimanipulasi pada suatu transaksi. Dengan kata lain, row-level trigger mengerjakan trigger action satu kali untuk setiap row yang sedang dimanipulasi. Penerapan trigger ini ditunjukkan oleh adanya klausa FOR EACH ROW.
Statement-level trigger dieksekusi satu kali pada suatu transaksi, tanpa memperhatikan jumlah row yang terlibat. Misalnya, jika terdapat suatu transaksi yang menginsertkan 1000 row ke tabel, maka statement-level trigger hanya akan dieksekusi sekali saja.
b. Before and After Trigger
Karena trigger dipicu oleh suatu kejadian (event), maka eksekusinya bisa diatur apakah sebelum atau sesudah event tersebut.
Before trigger menjalankan trigger action sebelum event atau statement pemicu berlangsung. Oleh karena itu, trigger ini cocok digunakan untuk mendeteksi bilamana event boleh dilanjutkan maupun tidak. After trigger menjalankan trigger action setelah event terjadi.
Query Optimization 127
Kita mungkin akan berhubungan dengan data lama (old) dan data baru (new) yang terjadi dalam transaksi. Dalam trigger, dikenal istilah alias atau referensi, yaitu sejenis variabel yang menyimpan nilai dari suatu kolom dalam tabel. Alias terbagi menjadi dua, yaitu:
:old → variabel yang menyimpan nilai lama kolom sebelum trigger dieksekusi. :new → variabel yang menyimpan nilai baru kolom setelah trigger dieksekusi.
Untuk statement INSERT, alias yang digunakan hanya :new saja, yaitu untuk menyimpan nilai yang akan dimasukkan ke dalam tabel. Untuk UPDATE, alias yang digunakan adalah :new dan :old, sedangkan Untuk DELETE, hanya alias :old saja, yaitu untuk menyimpan nilai yang akan dihapus.
Alias dituliskan di depan nama kolom yang bersangkutan. Penulisannya adalah seperti :new.nama_kolom dan :old.nama_kolom.
c. Instead of Trigger
Instead of trigger hanya diperuntukkan bagi view dan diaktivasi jika terjadi perubahan pada base table (tabel asli). Trigger ini tidak dapat menggunakan UPDATE OF nama_kolom maupun BEFORE dan AFTER trigger.
Tipe-tipe trigger di atas dapat dikombinasikan menjadi 14 macam :
1. BEFORE INSERT row
2. BEFORE INSERT statement
3. AFTER INSERT row
4. AFTER INSERT statement
5. BEFORE UPDATE row
6. BEFORE UPDATE statement
7. AFTER UPDATE row
8. AFTER UPDATE statement
9. BEFORE DELETE row
10. BEFORE DELETE statement
11. AFTER DELETE row
12. AFTER DELETE statement
13. INSTEAD OF row
14. INSTEAD OF statement
8.6 BATASAN TRIGGER
Dalam penggunaannya, trigger memiliki batasan sebagai berikut:
Tidak dapat menggunakan perintah ROLLBACK dan COMMIT. Tidak dapat memanggil fungsi dan prosedur yang memiliki
ROLLBACK dan COMMIT. Tidak dapat diimplementasikan pada kolom suatu tabel yang memiliki constraint, jika pada akhirnya akan menyebabkan pelanggaran constraint.
Query Optimization 129
8.7 STUDI KASUS
Sebuah apotek mempunyai database yang di dalamnya terdapat tabel-tabel dengan spesifikasi antara lain sebagai berikut:
Tabel obat id_obat id_pemasok
stok harga DT01
Table penjualan no_nota
total 2110
id_obat
Table histori_harga id_obat
berlaku 2110
harga_asli
persen_laba
25 14-MAR-2006
SQL> CREATE OR REPLACE TRIGGER aft_ins_row_penjualan
2 AFTER INSERT ON penjualan
3 FOR EACH ROW
4 BEGIN
5 IF INSERTING THEN
6 UPDATE obat
7 SET stok = stok - :new.jumlah
8 WHERE id_obat = :new.id_obat;
Trigger created.
Contoh 10.1
Trigger dimaksudkan untuk mengupdate tabel obat secara otomatis jika terjadi insert pada tabel penjualan. Alias :new.jumlah dan :new.id_obat berisi data baru tabel penjualan. Sedangkan stok dan id_obat merupakan kolom dari tabel obat. Untuk mengetahui kebenaran dari trigger, maka kita bisa mencoba statement berikut:
SQL> INSERT INTO penjualan VALUES(2111, 'DT01', 5, 20000);
1 row created.
SQL> SELECT id_obat, merk, stok, harga FROM obat; ID_OBAT MERK STOK HARGA ------------ -------------- --------- -------- DT01 Decolgen
Terlihat bahwa stok obat berkurang secara otomatis setiap terjadi insert pada penjualan.
Contoh 10.2
Perhatikan penggunaan :old dan :new.
SQL> CREATE OR REPLACE TRIGGER aft_upd_row_penjualan
2 AFTER UPDATE OF persen_laba ON histori_harga
3 FOR EACH ROW
4 BEGIN
5 IF UPDATING THEN
6 UPDATE obat
7 SET harga = :old.harga_asli + ((:old.harga_asli *
8 Query Optimization 131
:new.persen_laba)/100)
9 WHERE id_obat = :old.id_obat;
Trigger created.
Untuk mengetahui kebenaran trigger di atas, maka lakukan statementdi bawah. Akan terlihat bahwa trigger mengubah nilai pada kolom harga pada tabel obat apabila dilakukan updating pada kolom persen_laba pada tabel histori_harga.
SQL> update histori_harga set persen_laba = 50;
1 row updated.
SQL> SELECT id_obat, merk, stok, harga FROM obat; ID_OBAT MERK STOK HARGA ------------ -------------- --------- -------- DT01 Decolgen 195
Contoh 10.3
Perhatikan baik-baik contoh trigger berikut ini.
SQL> CREATE OR REPLACE TRIGGER aft_upd_row_obat
2 AFTER UPDATE OF id_obat ON obat
3 FOR EACH ROW
4 BEGIN
5 IF UPDATING THEN
6 UPDATE histori_harga SET id_obat = :new.id_obat
7 WHERE id_obat = :old.id_obat;
Trigger created.
Untuk mengecek trigger di atas, eksekusi statement berikut ini:
SQL> UPDATE obat SET id_obat='DT02' WHERE id_obat='DT01';
Maka hasilnya akan terlihat seperti di bawah ini:
SQL> UPDATE obat SET id_obat='DT02' WHERE id_obat='DT01'; UPDATE
id_obat='DT02' WHERE id_obat='DT01' * ERROR at line 1:
obat
SET
ORA-02292: integrity constraint
(SCOTT.SYS_C001394) violated - child record found
Query Optimization 133
Error yang terjadi disebabkan karena adanya constraint foreign key antara tabel obat, histori_harga, dan penjualan. Jika terjadi pengubahan id_obat pada tabel obat, trigger hanya dimaksudkan untuk mengubah id_obat pada tabel histori_harga, namun tidak demikian pada tabel penjualan. Hal inilah yang menyebabkan error.
Berikut ini perbaikan dari trigger di atas yang tidak akan menyebabkan pelanggaran constraint:
SQL> CREATE OR REPLACE TRIGGER aft_upd_row_obat
2 AFTER UPDATE OF id_obat ON obat
3 FOR EACH ROW
4 BEGIN
5 IF UPDATING THEN
6 UPDATE histori_harga SET id_obat = :new.id_obat
7 WHERE id_obat = :old.id_obat;
8 UPDATE penjualan SET id_obat=:new.id_obat
9 where id_obat=:old.id_obat;
Trigger created.
SQL> UPDATE obat
id_obat='DT02' WHERE id_obat='DT01';
SET
1 row updated.
8.8 MENGUBAH STATUS TRIGGER
Pada saat diciptakan, trigger berstatus aktif (enable). Kita dapat mengubah status trigger dengan perintah-perintah berikut:
ALTER TRIGGER nama_trigger DISABLE Sintaks tersebut digunakan untuk menonaktifkan trigger yang dibuat. ALTER TABLE nama_tabel DISABLE ALL TRIGGER Syntax tersebut digunakan untuk menonaktifkan semua trigger yang ada pada suatu tabel.
ALTER TRIGGER nama_trigger ENABLE ALTER TABLE nama_tabel ENABLE ALL TRIGGER DROP TRIGGER nama_trigger
Syntax tersebut digunakan untuk menghapus trigger yang telah dibuat.
8.9 Menonaktifkan Trigger
Sintaks:
ALTER TRIGGER nama_trigger DISABLE | ENABLE
Keterangan: DISABLE :
untuk menonaktifkan trigger yang sudah dibuat
ENABLE : untuk mengaktifkan kembali trigger yang sudah di DISABLE.
Contoh 10.4 :
Untuk men-disable trigger UPDATE_PEGAWAI, gunakan sintaks berikut:
ALTER TRIGGER UPDATE_PEGAWAI DISABLE
Query Optimization 135
Rangkuman
1. Trigger adalah blok PL/SQL atau prosedur yang berhubungan dengan table, view, skema atau database yang dijalankan secara implicit pada saat terjadi event.
2. Tipe dari trigger adalah : Application trigger (diaktifkan pada saat terjadi event yang berhubungan dengan sebuah aplikasi) dan database trigger (diaktifkan pada saat terjadi event yang berhubungan dengan data)
3. Trigger dibuat pada saat yang tepat jika diperlukan yaitu untuk membentuk sebuah aksi tertentu terhadap suatu event dan memusatkan operasi global
4. Penggunaan trigger yang terlalu berlebihan akan menyebabkan terjadi sifat ketidaktergantungan yang terlalu kompleks sehingga akan mempersulit pemeliharaan dari aplikasi yang besar.
5. Trigger berisi komponen-komponen : trigger timing, trigger event, nama tabel, tipe trigger, klausa WHEN dan trigger body.
6. Beberapa event pada trigger bisa dikombinasikan dalam sebuah trigger dengan menggunakan predikat kondisional INSERTING, UPDATING dan DELETING
7. Pada Row Trigger, nilai dari kolom sebelum dan sesudah perubahan data dapat dirujuk dengan menggunakan OLD dan NEW qualifier.
Latihan
pembayaran
PK id_pembayaran
meeting_room
memiliki style
PK
id_mr
pembayaran_kartu
PK
id_punya_style PK id_style
pembayaran_tunai
nama_mr
tgl_pembayaran
tarif_mr
kapasitas nama_style
id_reservasi
ukuran
id_mr id_style
fasilitas reservasi
pesan_fasilitas
id_pesan_fasilitas PK id_fasilitas PK
PK
jum_pesan_fasilitas nama_fasilitas pemesan
id_reservasi
tgl_reservasi biaya_total_fasilitas harga_fasilitas
PK id_pemesan
kegunaan
jum_min_fasilitas jum_org
id_reservasi id_fasilitas
jum_max_fasilitas nama_pemesan
tgl_awal alamat_pemesan
tgl_akhir no_telp
jam_awal jam_akhir
id_pemesan id_punya_style id_petugas
banquet
pesan_banquet
PK id_banquet
PK
id_pesan_banquet
petugas nama_banquet jum_pesan_banquet
jenis_banquet
PK id_petugas
biaya_total_banquet harga_banquet
jum_min_banquet nama_petugas
id_reservasi
jum_max_banquet jabatan
id_banquet
1. Buatlah sebuah trigger yang dapat menginputkan nama dan tanggal user yang logon pada database di dalam sebuah table. Hasil table tersebut seperti di bawah ini :
Note : gunakan database event.
2. Berikan contoh instead of trigger berdasarkan studi kasus KPK di atas!
Query Optimization 137
3. Suatu partai akan dapat diikutsertakan dalam pemilu jika partai tersebut memiliki jumlah anggota minimal 100 orang. Buatlah trigger yang akan memeriksa jumlah anggota suatu partai jika partai tersebut ingin diikutsertakan dalam pemilu!
4. Buatlah contoh row level trigger dan statement level berdasarkan studi kasus KPK, kemudian analisa perbedaannya!
5. Jika ID_Petugas seorang petugas KPU berubah maka ID_Petugas pada tabel mendaftar pun harus berubah. Mengapa demikian? Bagaimana triggernya?
9 Query Optimization
Overview
Proses dari optimisasi query meliputi tahapan-tahapan yang harus dilalui oleh suatu query tree dalam sebuah optimizer sehingga akan menghasilkan perencanaan aljabar secara fisik yang optimal, yang nantinya akan dijalankan untuk menghasilkan query yang diinginkan.
Tujuan
1. Mahasiswa memahami konsep optimasi query.
2. Mahasiswa memahami konsep dan algoritma sorting
3. Mahasiswa dapat memahami dan menggunakan operator relational
4. Mahasiswa dapat memahami algoritma join
Query Optimization 139
9.1 Query Optimization
Query Optimazion dalah proses dimana DBMS (Optimizer) menunjukkan strategi yang terbaik untuk menjalankan suatu query. Tugas utama optimizer adalah menemukan plan yang baik untuk mengevaluasi ekspresi. Dalam melakukan optimalisasi query harus memperhatikan cara alternatif untuk mengevaluasi suatu query yaitu :
Ekuivalent ekspression Beberapa algoritma untuk beberapa operasi.
Tahap yang harus dilakukan pada saat melakukan optimalisasi query adalah evaluation plan yaitu secara tepat menentukan algoritma apa yang akan digunakan dan bagaimana mengeksekusi algoritma tersebut pada operasi- operasi yang ada.
Optimalisasi ekspresi aljabar relasional melibatkan dua langkah besar yaitu: Mengumpulkan rencana alternatif untuk mengevaluasi ekspresi. Biasanya, optimizer dianggap sebagai subset dari semua plan yang mungkin karena jumlah plan yang ada sangat banyak.
Memperkitakan cost tiap plan yang terkumpul dan memilih plan dengan perkiraan cost paling rendah
Optimizer Mode :
a. Cost based optimizer Optimizer akan memutuskan rencana eksekusi (execution plan ) mana yang terbaik dan paling efisien dengan mempertimbangkan pada ketersediaan path aksesnya dan juga berdasar pada statistik informasi untuk skema objek (tabel/indeks) yang di akses oleh sebuah sql statement. Secara konsep, pendekatan cost-based terdiri atas 3 langkah berikut : Optimizer membangkitkan seperangkat rencana eksekusi yang
potensial untuk SQL Statement berdasar pada ketersediaan path dan petunjuk tentang sql statement tersebut.
Optimizer memperhitungkan cost pada tiap rencana eksekusi berdasarkan statistik pada kamus data untuk distribusi data dan karakteristik maupun informasi tentang penyimpanan dari tabel , indeks , dan partisi yang di akses oleh sebuah sql statement.
Optimizer membandingkan biaya setiap execution plan, dan kemudian memilih plan dengan biaya paling rendah
Note :
• Cost dapat diartikan sebagai sebuah nilai resource yg dibutuhkan untuk eksekusi sql statement dr beberapa execution plannya • Optimizer menghitung cost dari tiap kemungkinan metode akses dan urutan pen-joinan berdasar estimasi resource seperti CPU time, memori,I/O untuk ekseskusi statement sql menggunakan plan
• Execution plan secara serial dengan cost besar butuh waktu eksekusi lebih banyak daripada cost yg kecil • Execution plan secara parallel, penggunaan resource tidak langsung
berpengaruh pada waktu yg dibutuhkan untuk eksekusi statement sql
b. Rules based optimizer Optimizer memilih apakah menggunakan akses path pada beberapa pertimbangan faktor sebagai berikut :
1. Ketersediaan akses path pada tiap statement optimizer akan mengamati kondisi statement klausa WHERE untuk memutuskan akses path yg tersedia ( urutan kondisi dalam sebuah klausa WHERE tidak mempengaruhi )
Query Optimization 141
2. Peringkat access path tersebut optimizer memilih akses path dengan peringkat terbanyak dan
tertinggi
Tahapan proses optimisasi query secara umum adalah sebagai berikut :
1. Memasukkan query ke dalam representasi internal berdasarkan ekspresi aljabar yang sesuai.
2. Mengkonversikannya ke dalam bentuk canonical dengan cara mula-mula dengan menggunakan cartesian product dari klausa FROM, setelah itu menggabungkan dan memilih kondisi-kondisi dari klausa WHERE dan melakukan proyeksi-proyeksi dari klausa SELECT.
3. Memilih calon-calon prosedur low level, yaitu mempertimbangkan index- index atau jalan akses lainnya, membagi nilai-nilai penyimpanan data dari record-record untuk memilih satu atau lebih calon-calon prosedur untuk mengimplementasikan tiap-tiap operasi low level dalam query.
4. Menghasilkan rencana-rencana query dan memilih yang termurah, yaitu membuat sekumpulan calon rencana-rencana query dan kemudian memilih yang termurah.
Sebelum proses optimisasi query dilakukan, sebuah query harus diproses dahulu di dalam parser untuk mengecek kevalidan query tersebut dan kemudian query tersebut diterjemahkan ke dalam sebuah bentuk internal, yaitu ekspresi relasi aljabar. Biasanya, hasil dari proses parsing di dalam parser adalah berupa sebuah bentuk tree yang disebut dengan parse tree.
Jika suatu ekspresi aljabar relasional mengandung lebih dari satu operasi primitif (select, project, join) maka ada dua cara untuk melaksanakan operasi- operasi ini:
a. Materialization Evaluasi Materialization: evaluasi satu operasi pada satu waktu, dimulai dari yang paling dalam. Gunakan hasil antara (intermediate result) untuk materialisasi (membuat relasi temporer) untuk mengevaluasi operasi level berikutnya. Contoh: pada gambar di bawah, hitung dan simpan
balance 2500 account
Evaluasi dengan materialisasi selalu dapat dilakukan. Tetapi cost untuk menuliskan hasil ke disk dan membacanya kembali dapat sangat tinggi. Rumus perhitungan cost untuk masing-masing operasi (bagian sebelumnya) mengabaikan biaya untuk menuliskan hasil ke disk, sehingga • Cost keseluruhan = Jumlah cost masing-masing operasi + cost untuk
menuliskan hasil-hasil antara ke disk Untuk mempercepat materialisasi dilakukan dengan double buffering: menggunakan dua output buffer untuk masing-masing operasi, ketika satu buffer penuh maka tuliskan isinya ke disk sementara buffer yang lain diisi. Materialization memungkinkan penulisan ke disk dengan komputasi dilakukan secara bersamaan sehingga mengurangi waktu eksekusi
b. Pipelining Evaluasi Pipelining: merupakan evaluasi beberapa operasi secara bersamaan dan berikan hasil dari satu operasi ke operasi berikutnya. Contoh: di ekspresi sebelumnya, jangan simpan hasil dari
balance 2500 ( account ) Melainkan, berikan tuple langsung ke join. Dengan cara yang sama, jangan
simpan hasil join, berikan tuple langsung ke proyeksi. Cost yang dibutuhkan untuk melakukan pipelining lebih murah dari materialisasi karena tidak perlu menyimpan relasi temporer di disk. Namun, pipelining tidak selalu bisa dilakukan – misal, sort, hash-join. Agar pipelining efektif, gunakan algoritma yang membangkitkan output tuple pada saat tuple diterima sebagai input terhadap operasi tersebut. Pipeline dapat dilakukan dengan dua cara: demand driven dan producer driven
Query Optimization 143
Ekuivalences Rules
1. Conjunctive selection operation
1 2 ( E ) 1 ( 2 ( E ))
2. Selection operation
1 ( 2 ( E )) 2 ( 1 ( E ))
3. Projection operation t 1 ( t 2 ( ( tn ( E )) )) t 1 ( E )
4. Combine selection with cartesian product and theta join
a. (E 1 XE 2 )= E 1 E 2
b. 1 (E 1 2 E 2 )= E 1 1 2 E 2
5. Theta join operation (and natural joins) are commutative.
E E 2 1 =E 2 E 1
6. (a.) Natural join are associative:
(E 1 E 2 ) E 3 =E 1 (E 2 3 E )
(b.) Theta Join are associative in the following manner (E
7. The selection operation distributes over the theta join operation under the following two conditions:
(a) When all the attributes in 0 involve only the attributes of one of
being joined.
0 E 1 E 2 ) = ( 0 (E 1 ))
(b) When 1 involves only the attributes of E 1 and 2 involves
only the attributes of E 2 .
1 E 1 E 2 ) = ( 1 (E 1 ))
( (E 2 ))
8. The projections operation distributes over the theta join operation as follows: (a)
attributes from L 1 L 2
if P involves
only
L 2 2 )) (b) Consider a join E
( E E ) ( ( E )) ( ( E
L 1 L 2 1 ....... 2 L 1 1 ......
Let L 1 and L 2 be sets of attributes from E 1 and E 2 , respectively. Let L 3 be attributes of E 1 that are involved in join condition , but are not in L 1 L 2 , and let L 4 be attributes of E 2 that are involved
in join condition , but are not in L 1 L 2 .
L 1 L 2 ( E 1 ..... E 2 ) L 1 L 2 (( L 1 L 3 ( E 1 )) ...... ( L 2 L 4 ( E 2 )))
9. Set operations union and intersection
E 1 E 2 =E 2 E 1
E 1 E 2 =E 2 E 1 (*set difference is not commutative *).
10. Set union and intersection are associative
(E 1 E 2 )E 3 =E 1 (E 2 E 3 ) (E 1 E 2 )E 3 =E 1 (E 2 E 3 )
11. The selection operation distributes over , and –.
(E 1 – E 2 )= (E 1 ) – (E 2 )
and similarly for and in place of –Also:
(E 1 – E 2 )= (E 1 ) – E 2
and similarly for in place of –, but not for
12. The projection operation distributes over union
L (E 1 E 2 ) = ( L (E 1 )) ( L (E 2 ))
9.2 Sorting
Sorting kumpulan record pada beberapa (search) key merupakan operasi yang sangat berguna. Key dapat berupa atribut tunggal atau daftar atribut terurut. Sorting perlu dilakukan dalam berbagai situasi, termasuk hal penting berikut:
1. Sorting record merupakan langkah pertama dalam bulk-loading tree index
2. Sorting berguna untuk menghilagkan salinan duplikasi pada kumpulan record
3. Algoritma yang digunakan secara luas untuk melakukan operasi aljabar relasional yang sangat penting, yang disebut join ,memrlukan tahap sorting
Query Optimization 145
Algoritma sorting :
a. Two-way Merge Sort Sederhana Algoritma ini hanya memanfaatkan 3 page memory utama dan hanya direpresentasikan untuk tujuan pedagogikal. Walaupun seluruh file tidak muat dalam memory utama yang tersedia, kita dapat menyortirnya dengan memecah file tersebut menjadi subfile yang lebih kecil, menyortir subfile tersebut kemudian menggabungkan subfile tersebut dengan menggunakan sejumlah kecil memory utama pada waktu tertentu. Pada tahap pertama, halaman dalam file dibaca satu per satu. Setelah halaman dibaca, record didalamnya disortir dan halaman tersortir (sorted run panjangnya satu halaman) ditulis. Quicksort atau teknik sorting dalam memory yang lain dapat digunakan untuk menyortir record pada halaman. Pada tahap berikutnya, pasangan run dari output dari tahap sebelumnya dibaca dan digabungkan untuk menghasilkan run yang panjangnya 2 kali lipat panjang sebelumnya. Jika jumlah halaman dalam file inputan 2 k , untuk beberapa k maka : -
tahap 0 menghasilkan 2 k run tersortir masing-masing satu halaman -
tahap 1 menghasilkan 2 k-1 run tersortir masing-masing dua halaman -
tahap 2 menghasilkan 2 k-2 run tersortir masing-masing empat halaman, dan seterusnya sampai tahap k menghasilkan satu run 2 k halaman tersortir.
Dalam tiap tahap, kita membaca setiap halaman dalam file, memproses dan menulisnya. Oleh karena itu, kita mempunyai dua disk I/O per halaman, per tahap. Jumlah tahap adalah [log 2 N]+1 dimana N adalah jumlah halaman dalam file. Biaya keseluruhan adalah 2N ([log 2 N]+1) I/O. Algoritma ini hanya memerlukan tiga halaman buffer dalam memory utama. Observasi ini memunculkan hal penting, jadi sekalipun kita mempunyai ruang buffer yang lebih, algoritma two-way merge sort sederhana tidak akan memanfaatkanya secara efektif.
gambar 11.2 a
Contoh : Dibawah ini terdapat file input dengan 7 buah halaman. Sorting tersebut memerlukan 2 tahap dan pada tiap tahap kita membaca dan menulis tujuh halaman , dengan total 56 I/O. Hasil ini sesuai dengan analisis sebelumnya karena:
2x7 ([log 2 N7+1)= 56.
gambar 11.2 b
ket : dark page pada gambar menunjukan apa yang akan terjadi pada file delapan halaman; jumlah tahap tetap empat ([log 2 8+1=4), tetapi kita membaca dan menulis halaman tambahan dalam tiap tahap dengan total
64 I/O.
b. External Sorting Algoritma ini memerlukan lebih dari tiga halaman buffer. Selain itu algoritma ini juga melakukan 2 modifikasi penting pada two-way merge sort : Pada tahap 0, baca B halaman dan sortir secara internal untuk
menghasilkan run [N/B] masing-masing B halaman (kecuali run terakhir, yang mungkin berisi lebih sedikit halaman).
Tahap i=1,2,... gunakan B-1 halaman buffer untuk input dan gunakan sisa halaman untuk output; dengan demikian kita melakukan (B-1) cara penggabungan dalam tiap tahap
Query Optimization 147
Keuntungan external sort: Mengurangi jumlah run yang dihasilkan oleh tahap 0 sampai
N1=[N/B] Dengan melakukan (B-1) cara penggabungan, jumlah tahap dapat dikurangi sehingga menjadi [log B-1 N1] +1
gambar 11.2 c
Contoh : Terdapat 5 buffer untuk mensort 108 halaman file,maka yang dilakukan adalah : -
tahap 0 menghasilkan [108/5]= 22 run tersortir, masing-masing 5 halaman kecuali run terakhir yang panjangnya 3 halaman
- tahap 1 menghasilkan [22/4]= 6 run tersortir, masing-masing 20 halaman kecuali run terakhir yang panjangnya 8 halaman
- tahap 2 menghasilkan [6/4]= 2 run tersortir, satu dengan 80 dan satu dengan 28 halaman
- tahap 3 menggabungkan dua run yang dihasilkan pada tahap 2 untuk menghasilkan file tersortir.
9.3 Operator Relational
9.3.1 Selection ( )
Selection merupakan salah satu operator yang digunakan untuk memilih (select) baris dari suatu relasi.
Contoh :
rating >8 )
(S2
Sid Sname Rating Age
28 Yuppy
Tabel S2
9.3.2 Projection ()
Perhatikan query dibawah ini :
SELECT DISTINCT R.sid, R.bid FROM Reserves R
Optomizer menterjemahkan query diatas menjadi aljabar relasional π sid.rid Reserves. Secara umum, operasi proyeksi merupakan bentuk π attr1.attr2 (R). Untuk melakukan proyeksi hal yang harus dilakukan adalah: -
membuang atribut yang tidak diinginkan (misalnya, yang tidak ditentukan pada proyeksi )
- menghilangkan tuple duplikat apapun yang dihasilkan contoh :
20 1 ∏ A,C
Ada dua algoritma untuk melakukan proyeksi, yaitu :
a. proyeksi berdasarkan sorting langkah-lagkah melakukan proyeksi dengan sorting: - men-scan R dan menghasilkan kumpulan tuple yang hanya berisi atribut
yang diinginkan - menyortir kumpulan tuple ini menggunakan kombinasi dari semua atributnya sebagai key untuk sorting - men-scan hasil yang disortir, membandingkan tuple yang berdekatan dan membuang duplikat.
a. proyeksi berdasarkan hashing jika kita mempunyai banyak page buffer, maka pendekatan hash-based bisa dipertimbangkan. Terdapat dua langkah untuk melakukan proyeksi dengan menggunakan algoritma ini : - tahap partisi
Pada tahap partisi kita mempunyai satu page buffer input dan B-1 pagebuffer output. Relasi R dibaca ke dalam page buffer input, setiap satu halaman. Halaman input diproses sebagai berikut: tiap tuple, kita memproyeksikan atribut yang tidak diinginkan lalu mengaplikasikan fungsi hash h pada kombinasi dari semua atribut yang ada. Fungsi h dipilih sehingga tuple didistribusikan secara seragam pada suatu B-1
Query Optimization 149 Query Optimization 149
Pada akhir partisi, kita mempunyai B-1 partisi, masing-masing berisi kumpulan tuple yang menggunakan nilai hash umum. Dua tuple yang tercakup dalam partisi yang berbeda dijamin tidak menjadi duplikat karena mereka mempunyai nilai hash yang berbeda. Jadi, jika dua tuple merupakan duplikat, maka mereka berada dalam partisi yang sama.
- tahap eliminasi duplikat kita membaca B-1 partisi satu per satu untuk menghilangkan duplikat.
9.3.3 Union ()
R S menghasilkan contoh relasi yang berisi semua tuple yang terjadi dalam contoh relasi R atau contoh relasi S (atau keduanya). R dan S haruslah union compatible dan skema hasil identik dengan skema R. Dua contoh relasi dikatakan union compatible jika memenuhi syarat berikut :
memiliki jumlah field yang sama field yang berurutan, dalam urutan dari kiri ke kanan, memiliki
doamain yang sama. Perhatikan bahwa nama field tidak digunakan dalam menentukan kompatibilitas union. Untuk memudahkan kita asumsikan bahwa field R S mewarisi nama dari R jika field R punya nama. Contoh :
Sid Sname Rating
Tabel S1
Sid Sname Rating Age
5 35.0 S1 S2
58 Rusty
Tabel S2
9.3.4 Set-Difference
Operasi set-difference (R-S) menghasilkan salah satu contoh relasi yang berisi semua tuple yang terjadi baik pada R dan S. Relasi R dan S harus union compatible, dan skema hasil ditentukan identik dengan skema R. Contoh :
Sid Sname Rating
Tabel S1 }
S1- S2
Sid Sname Rating Age
Tabel S2
9.3.5 Algoritma Join
Ada beberapa algoritma berbeda untuk implementasi join, yaitu :
a. Nested-loop join
Algoritma untuk menghitung theta join r s
for each tuple tr in r do begin for each tuple ts in s do begin
test pair (tr,ts) to see if they satisfy the join condition if they do, add tr • ts to the result.
end end
Dimana r disebut sebagai relasi luar (outer relation) dan s sebagai relasi dalam (inner relation) dari join. Algoritma join ini tidak membutuhkan indeks sehingga dapat digunakan dalam kondisi join apapun.
Query Optimization 151
Kelemahan dari algoritma ini adalah mempunyai cost yang mahal, karena harus memeriksa setiap pasangan tuple di kedua relasi. Dalam keadaan paling buruk (worst case), jika hanya mempunyai memory yang mampu menampung satu blok dari masing-masing relasi, perkiraan cost adalah
nr * Bs + br
Jika relasi yang lebih kecil dapat masuk seluruhnya ke dalam memory, maka gunakan itu sebagai relasi bagian dalam. Mengurangi biaya menjadi br + bs disk access. Contoh : Terdapat catalog berisi informasi berikut ini: - n customer = 10,000 - f customer = 25, sehingga bcustomer=10000/25=400 - n depositor =5000 - f depositor =50, sehingga bdepositor=5000/50=100 - V (customer-name,depositor ) = 2500, rata-rata tiap nasabah punya dua rekening
Jawab :
Dengan mengasumsikan worst case, maka perkiraan biaya akan menjadi – 5000*400 + 100 = 2,000,100 disk acess dengan depositor sebagai relasi
luar (outer relation) – 1000*100+400 = 1,000,400 disk access dengan customer sebagai relasi bagian luar
Jika relasi yang lebih kecil (depositor) dapat masuk seluruhnya di memory, maka perkiraan biaya akan menjadi 500 disk access.
b. Block nested-loop join
Algoritma ini merupakan jenis lain nested-loop join di mana masing- masing blok dari inner relation dipasangkan dengan outer relation. Algoritma block nested-loop join :
for each block Bs of s do begin for each tuple tr in Br do begin for each tuple ts in Bs do begin
Check if (tr,ts) satisfy the join condition
if they do, add tr • ts to the result.
end end end end
Cost yang dibutuhkan : worst case: br*bs+br block access Masing-masing blok di relasi bagian dalam s dibaca satu kali untuk masing-masing blok di relasi bagian luar (bukannya satu kali untuk masing-masing tuple di relasi bagian luar)
Best case: br+bs block access Perbaikan terhadap algoritma nested loop dan blok nested loop: Dalam blok nested-loop, gunakan M-2 disk blok sebagai ukuran blok
untuk relasi bagian luar, di mana M = ukuran memory dalam blok; gunakan sisanya yang dua blok untuk menampung relasi bagian dalam dan outputnya Cost = [br/(M-2)] * bs + br
Jika atribut equi-join merupakan kunci pada relasi bagian dalam, hentikan loop di bagian dalam (inner loop) pada saat pertama kali ditemukan nilai yang cocok
Scan inner loop ke depan (forward) dan ke belakang (backward) secara bergantian, sehingga blok yang masih ada di buffer dapat digunakan
Gunakan indeks di relasi bagian dalam jika tersedia (Indexed nested loop join)
c. Indexed nested-loop join
Indeks lookup dapat menggantikan file scan (pembacaan seluruh file) jika: – Join adalah equi-join atau natural join dan
– Ada indeks untuk atribut join relasi bagian dalam (inner relation‘s join attribute) Bisa saja membangun indeks hanya untuk menghitung sebuah operasi join
Untuk masing-masing tuple tr di relasi luar r, gunakan indeks untuk mencari tuple di s yang memenuhi kondisi join dengan tuple tr. Pada keadaan worst case buffer hanya mempunyai ruang (space) untuk satu blok r, dan, untuk tiap-tiap tuple di r, kita melakukan indeks lookup di s Cost dari join ini adalah: br + nr*c
– Di mana c adalah cost untuk menjelajahi indeks dan mengambil
semua tuple s yang cocok untuk satu tuple – C dapat dianggap sebagai cost untuk satu buah operasi selection
pada s menggunakan kondisi join Jika terdapat indeks pada atribut-atribut join baik di r dan s, gunakan relasi dengan tuple lebih sedikit sebagai relasi bagian luar
Query Optimization 153 Query Optimization 153
Join jenis ini dapat digunakan hanya untuk equi-join dan natural join dimana masing-masing blok hanya perlu dibaca sekali (asumsi semua tuple hasil join dapat masuk ke dalam memory) sehingga jumlah blok akses yang diperlukan untuk merge join adalah Br+bs+cost untuk mengurutkan relasi yang belum urut Hybrid merge-join: Jika satu relasi telah diurutkan, sementara yang lainnya mempunyai indeks sekunder B+-tree pada atribut joinnya, maka: - Gabungkan relasi yang telah urut tersebut dengan nilai-nilai di node leaf
pada B+-tree - Urutkan hasil pada tuple yang belum terurut berdasarkan alamat- alamat fisik penyimpanan tuple relasi yang belum terurut - Pelaksanaan operasi join dilakukan berdasarkan urutan alamat fisik relasi yang belum terurut tersebut
penelusuran secara sequensial lebih efisien dar penelusuran secara acak
gambar 11.4 a skema Merge join
ket : - Urutkan kedua buah atribut relasi (jika belum diurutkan pada atibut join) - Gabungkan relasi yang sudah diurutkan
Hash join berlaku untuk equi-join dan natural join.
gambar 11.4 b skema Hash join
Hash join r (build input)dan s (probe input) dilakukan sebagai berikut:
1. Partisi relasi s menggunakan fungsi hash h. Pada saat mempartisi sebuah relasi, satu blok memory dipesan untuk menampung (buffer) output masing-masing partisi
2. Lakukan hal yang sama pada r
3. Untuk masing-masing i: – Masukan si ke dalam memory dan bangun indeks hash di dalam
memory (in-memory) untuk relasi si tersebut. Indeks hash ini menggunakan fungsi hash berbeda daripada yang terdahulu h.
– Bacalah tuple di ri dari disk satu demi satu. Untuk masing- masing tuple tr temukan masing-masing tuple ts di si
menggunakan indeks hash in-memory. Keluarkan gabungan atribut-atributnya.
4. Nilai n dan fungsi hash h dipilih sehingga masing-masing si dapat masuk ke dalam memory.
– Secara khusus n dipilih sebagai [bs/M]*f di mana f adalah ―fudge factor‖, biasanya bernilai sekitar 1.2 – Partisi-partisi probe relation si tidak harus masuk ke dalam memory
Query Optimization 155
5. Recursive partitioning diperlukan jika banyaknya partisi n lebih besar daripada banyaknya page M dari memory.
– Daripada mempartisi n kali, gunakan M-1 partisi untuk s – Partisi lebih lanjut M-1 menggunakan fungsi hash yang berbeda – Gunakan metode partisi yang sama untuk r – Jarang sekali digunakan: recursive partitioning tidak diperlukan
untuk relasi-relasi yang lebih kecil atau sama dengan 1GB dengan ukuran memory 2MB, dengan ukuran blok 4KB
Cost hash join : • Jika recursive partitioning tidak diperlukan: cost hash join adalah
3(br + bs) +2 nh • Jika diperlukan recursive partitioning, banyaknya tahap yang
diperlukan untuk melakukan partitioning s adalah logM–1(bs) – 1. Hal ini karena masing-masing partisi akhir dari s harus masuk dalam memory.
• Banyaknya partisi untuk relasi probe r adalah sama dengan untuk relasi build s; banyaknya tahap partisi untuk r adalah sama dengan
untuk s. • Karenanya paling baik jika memilih relasi yang lebih kecil sebagai build relation. • Perkiraan cost totalnya adalah: 2(br + bs logM–1(bs) – 1 + br + bs • Jika seluruh build input dapat disimpan di main memory, maka n dapat diset ke 0 dan algoritma tidak mempartisi relasi ke dalam file
temporer. Sehingga perkiraan cost turun menjadi br + bs Contoh : memory berukuran 20 blok dengan b depositor =100 dan b customer =400, maka :
• depositor digunakan sebagai build input. Dipartisi menjadi lima partisi, masing-masing berukuran 20 blok. Proses partisi ini dapat dilakukan dalam satu tahap.
• Dengan cara yang sama, customer dipartisi menjadi lima partisi,
masing-masing berukuran 80 blok, dilakukan dalam satu tahap. • Sehingga total cost: 3(100+400) = 1500 blok transfer
– Abaikan cost untuk menulis blok yang sudah sebagian penuh
Rangkuman
1. Adalah proses dimana DBMS (Optimizer) menunjukkan strategi yang terbaik untuk menjalankan suatu query
2. Optimalisasi query merupakan hal yang sangat penting pada relasional DBMS
3. Dibutuhkan pemahaman yang baik pada saat melakukan optimasi query karena optimalisasi query bedampak pada performansi data pada saat di load
4. Dua hal yang harus diperhatikan saat melakukan optimasi query adalah alternative plan dan cost yang dibutuhkan untuk eksekusi plan tersebut.
5. Eksternal sort dapat mengurangi cost disk I/O
Query Optimization 157
Latihan
1. Mengapa optimalisasi perlu dilakukan?
2. Hal-hal apa saja yang harus diperhatikan pada saat melakukan optimalisasi query?
3. Sebutkan langkah-langkah dalam melakukan optimalisasi query?
4. Apa kelebihan cost-based optimizer?
5. Apa keuntungan jika suatu data di sorting?
6. Sebutkan perbedaan algoritma external sort dan two-way sort!
7. jelaskan tahapan yang dilakukan untuk melakukan sorting jika kita mempunyai 8 buffer untuk mensort 99 halaman file!
8. Apa perbedaan mendasar dari selection dan projection?
9. dari Algoritma join yang ada, algoritma mana yang membutuhkan cost yang paling murah?
10. hitunglah cost yang dibutuhkan dengan menggunakan metode nested loop join dan blok nested loop join jika : n customer = 50.000
f customer = 100 n depositor =1500
f depositor =10
V (customer-name,depositor ) = 250, rata-rata tiap nasabah punya dua rekening
11. Buatlah ekspresi aljabar relasional query dibawah ini : SELECT P.NUMBER,
P.DNUM, E.LNAME, E.ADDRESS, E.BDATE FROM PROJECT AS P, DEPARTMENT AS D, EMPLOYEE AS E WHERE P.DNUM=D.DNUM AND D.MGRSSN=E.SSN
AND
P.LOCATION=’Stafford’ ;