Praktikum 2
CURSOR
Tujuan :
1.
Mengetahui dan mengerti CURSOR
2.
Mampu mengimplementasikan CURSOR dalam pemrograman di
Oracle
Alat dan Bahan :
1.
Buku literatur mengenai PL/SQL ORACLE, terutama yang
menggunakan DBMS ORACLE 10g.
2.
Modul praktikum BASIS DATA LANJUT
3.
Modul praktikum DATA MINING DAN WAREHOUSING
Landasan Teori :
1. Pendahuluan
Blok PL/SQL tidak memungkinkan
untuk menangani query dengan keluaran lebih dari satu baris(record) karena
variabel penampungnya harus mempunyai sebuah nilai. Karena itu, diperlukan sebuah cursor untuk menampung
semua kondisi dari keluaran sebuah query. Cursor merupakan suatu variabel yang
digunakan untuk menampung hasil query
yang terdiri atas lebih dari satu
row atau record.
Cursor dapat diilustrasikan sebagai penampung sekaligus
pointer atas hasil
eksekusi query. Pada
dasarnya perintah “SELECT ..” pada PL/SQL merupakan sebuah cursor.
Terdapat dua macam cursor, yaitu: cursor implisit dan cursor eksplisit
2. Cursor Implisit
Merupakan perintah SELECT
statement dengan klausa INTO yang terdapat di dalam blok PL/SQL dan harus
menghasilkan satu baris record. Jika hasil cursor implisit ini lebih dari satu
baris atau tidak menghasilkan satu baris pun, maka Oracle akan mengeluarkan
pesan kesalahan. Klausa into pada cursor implisit dipakai untuk menugaskan
nilai hasil proses select ke dalam variabel-variabel yang dipilih.
Atribut
|
Keterangan
|
SQL%FOUND
|
TRUE jika cursor menghasilkan sebuah baris
dari queri yang dideklarasikan. Sebaliknya FALSE.
|
SQL%NOTFOUND
|
Kebalikan dari %FOUND
|
SQL%ROWCOUNT
|
Jumlah baris yang telah diambil/ditangkap
(FETCH)
|
SQL%ISOPEN
|
Mengembalikan nilai TRUE jika cursor masih
dalam keadaan terbuka (OPEN)
|
Contoh:
DECLARE mhs_rec
mahasiswa%ROWTYPE; nim_nya
mahasiswa.nim%TYPE;
BEGIN nim_nya := '30108001';
SELECT nim, nama, alamat INTO mhs_rec FROM nahasiswa WHERE nim
= nim_nya;
END;
|
Jika nilai nim sama dengan
30108001 dipenuhi maka hasil proses select menghasilkan satu baris, sedangkan
jika nilai nim_nya diganti dengan nilai lain dimana nilai tersebut tidak akan
menghasilkan satu baris pun, maka Oracle akan mengeluarkan pesan kesalahan.
Demikian pula jika klausa where pada cursor di atas dihilangkan sementara di
dalam tabel proyek terdapat lebih dari satu baris, maka cursor tersebut tidak
dapat menampung semua baris yang diterima. Hal ini akan menimbulkan error
“exact fetch returns more than requested number of rows”.0020
IMPLICIT CURSOR CONTOH 1.
DECLARE vnim
mahasiswa.nim%TYPE:='&nim_mhs';
vnama
mahasiswa.nama%TYPE;
BEGIN
SELECT
nim,nama INTO vnim,vnama FROM mahasiswa
WHERE nim=vnim;
DBMS_OUTPUT.PUT_LINE('Nim
: '||vnim);
DBMS_OUTPUT.PUT_LINE('Nama
mahasiswa : '||vnama); EXCEPTION
WHEN
NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak
ada mahasiswa dengan nim :
'||vnim);
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Data yang dihasilkan lebih dari 1 baris');
END;
/
|
IMPLICIT CURSOR CONTOH 2
DECLARE
vnim mahasiswa.nim%TYPE:='&nim_mhs'; vnama mahasiswa.nama%TYPE; n number;
BEGIN
SELECT nim,nama INTO
vnim,vnama FROM mahasiswa WHERE nim=vnim;
n :=
SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('Data
Mahasiswa');
IF SQL%FOUND
THEN DBMS_OUTPUT.PUT_LINE('Nim : '||vnim);
DBMS_OUTPUT.PUT_LINE('Nama
: '||vnama);
DBMS_OUTPUT.PUT_LINE('Jumlah
data : '||n);
END IF;
EXCEPTION
WHEN
NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak
ada mahasiswa dengan nim:
'||vnim);
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Data
yang dihasilkan lebih dari 1
baris');
END;
/
|
IMPLICIT CURSOR CONTOH 3.
DECLARE
vnama
mahasiswa.nama%TYPE:='&nama_mhs';
-- masukkan paijo misal ada 2 mahasiswa
dengan nama depan paijo
n
number;
BEGIN
UPDATE
mahasiswa SET alamat='SKB' WHERE nama LIKE vnama||'%';
n := SQL%ROWCOUNT;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('Mahasiswa
dengan nama depan
'||vnama||'
telah di update');
DBMS_OUTPUT.PUT_LINE('Jumlah
data yang diupdate =
'||n);
ELSE
DBMS_OUTPUT.PUT_LINE('Tidak ada mahasiswa dengan nama depan
: '||vnama);
DBMS_OUTPUT.PUT_LINE('Jumlah
data yang diupdate = '||n);
END IF;
EXCEPTION
WHEN
TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Data
yang dihasilkan lebih dari 1
baris');
END;
/
|
3. Cursor
Eksplisit
Tidak seperti cursor implisit,
cursor eksplisit harus dideklarasikan terlebih
dahulu sebelum digunakan.
Terdapat empat tahapan penggunaan cursor eksplisit ini
yaitu:
declare, open, fetch dan terakhir
adalah close.
a. Statement declare:
CURSOR nama_cursor IS
query
|
Merupakan deklarasi nama cursor
dan definisi struktur query yang akan dilakukan di dalamnya.
Contoh:
DECLARE
CURSOR CUR1 IS
SELECT
nim, nama, alamat FROM mahasiswa
|
b. Statement open
OPEN nama_cursor; Sebelum
suatu cursor dapat digunakan, cursor harus dibuka terlebih dahulu.
|
Contoh:
OPEN CUR1;
|
c. Statement fetch
FETCH nama_cursor INTO
<variable1,variable2,..>;
|
Fetch merupakan perintah untuk
mengambil isi cursor, dimana isi dari cursor tersebut adalah hasil query yang
telah dideklarasikan pada statement deklarasi cursor. Dan tiap-tiap field hasil
query tersebut kemudian ditampung dalam variable-variable yang tipe datanya
sesuai dengan tipe-tipe kolom query pada
statemen deklarasi. Fetch ini
dilakukan untuk tiap-tiap baris. Contoh:
FETCH
CUR1 INTO v_nim, v_nama, v_alamat;
|
d. Statement close
CLOSE
nama_cursor;
Setelah
pemrosesan query selesai,
cursor harus ditutup
dengan satatemen CLOSE ini.
Berikut ini adalah
atribut-atribut untuk mendapatkan
status cursor. Setiap atribut dalam penggunaannya harus didahului dengan nama
cursor.
Atribut
|
Keterangan
|
nama_cursor%FOUND
|
TRUE jika cursor
menghasilkan sebuah baris dari query yang dideklarasikan. Sebaiknya FALSE.
|
nama_cursor%NOTFOUND
|
Kebalikan dari %FOUND
|
nama_cursor%ROWCOUNT
|
Jumlah baris yang di-fetch
atau diambil dari active set.
|
nama_cursor%ISOPEN
|
TRUE jika cursor sedang
terbuka dan FALSE jika sebaliknya.
|
Contoh:
DECLARE v_nama
varchar2(20); v_nim char(9);
CURSOR cur1 IS SELECT NAMA, NIM FROM
MAHASISWA;
BEGIN
OPEN cur1;
FETCH cur1 INTO v_nama, v_nim;
WHILE cur1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_nama);
DBMS_OUTPUT.PUT_LINE(v_nim);
FETCH cur1 INTO v_nama,
v_nim; END LOOP;
CLOSE CUR1;
END;
|
e. Cursor
FOR LOOP
Ada sebuah cara untuk mengambil isi cursor secara
otomatis, yaitu dengan struktur pengulangan FOR LOOP. Disebut otomatis karena
: • Tidak
perlu proses pembukaan cursor ( OPEN )
•
Memanipulasi proses pengambilan cursor ( FETCH )
•
Tidak perlu penutupan cursor ( CLOSE )
•
Variabel
indeks yang digunakan
dalam struktur pengulangan FOR_LOOP tidak perlu
dideklarasikan terlebih dahulu
Sintaks:
DECLARE
CURSOR nama_cursor IS
ekspresi-query
BEGIN
FOR
nama_record IN nama_cursor LOOP
--
nama_record tidak perlu dideklarasikan
END
LOOP
END;
|
Contoh:
DECLARE
CURSOR cur1 IS SELECT nama FROM
mahasiswa;
BEGIN
FOR rec IN cur1 LOOP
DBMS_OUTPUT.PUT_LINE(rec.nama);
END
LOOP END;
|
Nama record yang didefinisikan
sesudah for merupakan pendeklarasian yang hanya internal di dalam loop, dan
ruang lingkupnya bersifat internal sampai loop
berhenti. Sebenarnya di
dalam loop for,
cursor tidak harus dideklarasikan terlebih dahulu.
EKSPLISIT CURSOR CONTOH 1. (Menggunakan
LOOP-EXIT)
DECLARE vnim
mahasiswa.nim%TYPE; vnama mahasiswa.nama%TYPE;
CURSOR cursor1 IS
SELECT
nim,nama FROM mahasiswa; n number;
BEGIN
DBMS_OUTPUT.PUT_LINE('Data
Mahasiswa);
DBMS_OUTPUT.PUT_LINE('No Nim Nama');
OPEN
cursor1;
LOOP
FETCH cursor1 INTO vnim,
vnama;
EXIT WHEN
cursor1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(cursor1%ROWCOUNT||'.'||vnim||'
'||vnama);
END LOOP;
n := cursor1%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('Jumlah data = '||n);
CLOSE cursor1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak ada data mahasiswa');
END;
/
|
EKSPLISIT CURSOR CONTOH 2.(Menggunakan
WHILE-LOOP)
DECLARE vnim
mahasiswa.nim%TYPE; vnama mahasiswa.nama%TYPE;
CURSOR cursor1 IS
SELECT nim, nama FROM
mahasiswa; n number;
BEGIN
DBMS_OUTPUT.PUT_LINE('Data
Mahasiswa);
DBMS_OUTPUT.PUT_LINE('No Nim Nama');
OPEN cursor1;
FETCH cursor1 INTO vnim,vnama;
WHILE cursor1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(cursor1%rowcount||'.'||vnim||''||
vnama);
FETCH cursor1 INTO
vnim,vnama; END LOOP;
n := cursor1%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('Jumlah data =
'||n);
CLOSE cursor1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak ada data
mahasiswa);
END;
/
|
EKSPLISIT CURSOR CONTOH 3.(Menggunakan
FOR-IN-LOOP)
DECLARE
CURSOR cursor1 IS
SELECT nim,nama FROM
mahasiswa; n number;
BEGIN
DBMS_OUTPUT.PUT_LINE('Data
Mahasiswa);
DBMS_OUTPUT.PUT_LINE('No
Nim Nama');
FOR
x IN cursor1 LOOP -- x tidak perlu di
deklarasikan
DBMS_OUTPUT.PUT_LINE(cursor1%rowcount||'.'||x.nim||'
'||x.nama);
n := cursor1%ROWCOUNT;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Jumlah data =
'||n);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak ada data
mahasiswa');
END;
/
|
EKSPLISIT CURSOR CONTOH 4.
(Menggunakan FOR-IN-LOOP tanpa
mendeklarasikan cursor)
DECLARE n
number:=0;
BEGIN
DBMS_OUTPUT.PUT_LINE('Data
Mahasiswa);
DBMS_OUTPUT.PUT_LINE('No Nim Nama');
FOR x IN (SELECT nim,nama FROM
mahasiswa)
-- x tidak perlu di deklarasikan
LOOP n := n + 1;
DBMS_OUTPUT.PUT_LINE(n||'.'||x.nim||
''||x.nama);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Jumlah data =
'||n);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak ada data
mahasiswa');
END;
/
|
Tugas Pendahuluan :
1.
Jelaskan perbedaan antara cursor dengan perintah
SELECT!
2.
Jelaskan maksud dan keluaran dari blok PL/SQL dibawah
ini:
DECLARE vid_buku
buku.id_buku%TYPE; vjudul buku.judul%TYPE;
CURSOR cursor1 IS
SELECT id_buku,judul
FROM buku; n number;
BEGIN
DBMS_OUTPUT.PUT_LINE('Data Buku);
DBMS_OUTPUT.PUT_LINE(id_buku
Judul);
OPEN cursor1;
FETCH cursor1 INTO
vid_buku,vjudul;
WHILE cursor1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(cursor1%ROWCOUNT||'.'||vid_buku|
|' '||vjudul);
FETCH cursor1 INTO
vid_buku,vjudul; END LOOP;
n := cursor1%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('Jumlah
data = '||n); CLOSE cursor1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Tidak
ada data buku);
END;
/
|
Percobaan :
1.
Buat
User baru dengan nama NPM anda. Buat
tabel-tabel seperti pada ERD seperti
berikut lengkap dengan tipe data dan panjang data yang benar.
Kemudian isikan data-data berikut :
ID
SUPPLIER
|
NAMA
|
NO TELP
|
ALAMAT
|
SP-001
|
PT. Sidogiri
|
022-8768509
|
JL. Ruwet Gg. Buntet No. 34
Bandung
|
SP-002
|
PT. Moroseneng
|
021-8695465
|
JL. Badak Jawa No.6 Jakarta
|
SP-003
|
PT. Suka-Suka
|
031-4568698
|
JL Darmo No.7 Surabaya
|
SP-004
|
PT. Sukabaca
|
022-9797966
|
JL. Sukabirus No.9 Bandung
|
ID
BUKU
|
ID JENIS
|
ID
SUPPLIER
|
JUDUL
|
PENGARANG
|
HARGA
|
STOCK
|
BK-001
|
IT
|
SP-002
|
10 Langkah Belajar
Logika & Algoritma
Menggunakan
Bahassa C++
|
Ema
Utami
|
Rp. 27.375
|
10
|
BK-002
|
IT
|
SP-001
|
10 Langkah
Mempelajari Lotus
Notes 4.5
|
Jane
Calabria
|
Rp. 9.180
|
34
|
BK-003
|
BH
|
SP-004
|
Kamus Bahasa
Inggris
|
Jubilee
Enterprise
|
Rp. 15.980
|
65
|
BK-004
|
IT
|
SP-001
|
101 Tip & Trik
Adobe Photoshop
CS
|
Gregorius
Agung
|
Rp. 16.830
|
26
|
BK-005
|
BI
|
SP-001
|
101 Tip & Trik
Belajar Anatomi
Manusia
|
Gregorius
Agung
|
Rp. 19.380
|
84
|
BK-006
|
IT
|
SP-002
|
101 Tip & Trik Ms.
Access Project
2003 & Sql Server
2000
|
Hengky
Alexander M.
|
Rp. 16.830
|
36
|
BK-007
|
MN
|
SP-002
|
Konsep-Konsep
Marketing
|
Anwar
Khaidir
|
Rp. 12.580
|
26
|
BK-008
|
AG
|
SP-004
|
Renungan Jumat
|
Abdurrahma
Arroisi
|
Rp. 31.280
|
6
|
BK-009
|
UM
|
SP-003
|
11 Langkah
Menjadi Sahabat
Ana
|
V. Dwiyani
|
Rp. 19.380
|
2
|
BK-010
|
IT
|
SP-002
|
12 Kreasi Logo
Dengan Adobe
Illustrator CS2
|
Jubilee
Enterprise
|
Rp. 27.880
|
88
|
BK-011
|
UM
|
SP-004
|
13 Cara Praktis Memetik Sukses
|
R. Herry
Prasetyo
|
Rp. 16.830
|
25
|
Kemudian lakukan EXPORT dan simpan file hasil EXPORT
tersebut sehingga dapat di IMPORT kembali
dan digunakan pada praktikum berikutnya.
2.
Buatlah cursor implisit dan eksplisit yang menampilkan
data-data buku beserta suppliernya!
3.
Jalankan blok PL/SQL dibawah ini pada SQL Plus kemudian
jika terjadi error perbaiki :
DECLARE v_idsupplier
supplier.id_supplier%TYPE; v_nama supplier.nama%TYPE; v_no_telepon supplier.no_telepon%TYPE; v_alamat
supplier.alamat%TYPE;
BEGIN
SELECT
id_supplier,nama,no_telepon,alamat INTO
vid_supplier,vnama,vno_telepon,valamat
FROM supplier ORDER
BY id_supplier;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Nama Pemesan
Tidak Ditemukan');
ELSE
DBMS_OUTPUT.PUT_LINE('Daftar Nama
Pemesan yang
Total Banquetnya <= 500000
:');
DBMS_OUTPUT.PUT_LINE(v_npm);
END IF;
END;
/
|
0 komentar:
Post a Comment