Oracle Cursor dan Ref Cursor
January 6th, 2009
Definisi Cursor
Dalam blok PL/SQL tidak mengijinkan kita membuat query yang menghasilkan lebih dari satu baris untuk ditampung dalam sebuah variabel. Variabel semacam ini dinamakan cursor.
Kegunaan
- Untuk menerima hasil query yang jumlah barisnya lebih dari 1 baris
- Memungkinkan untuk melakukan proses yang lebih kompleks untuk setiap record
Macam2 Cursor
Cursor : cursor eksplisit dan cursor implisit
- Cursor Eksplisit : Cursor yang harus dideklarasikan terlebih dahulu sebelum digunakan
- Cursor Implisit : Cursor yang tidak perlu dideklarasikan dulu pada declare section. contoh cursor implisit diasosiasikan dengan perintah SELECT, INSERT, DELETE, dan UPDATE
Contoh :DECLARE id VARCHAR2(10); vnama_petugas PETUGAS.nama_petugas%TYPE; BEGIN id := 'PG-010'; //assigment value SELECT nama_petugas INTO vnama_petugas FROM PETUGAS WHERE id_petugas = id; IF SQL%NOTFOUND THEN DBMS_OUTPUT.PUT_LINE('Data ditemukan'); ELSE DBMS_OUTPUT.PUT_LINE ('Nama petugas dengan id : ' || id || 'adalah ' || vnama_petugas); END IF; END;
Contoh :
DECLARE CURSOR c_nama IS SELECT nama_petugas FROM pegawai ORDER BY nama_petugas ASC; v_nama PETUGAS.nama_petugas%TYPE; /**%TYPE agar tipe data variabel v_nama sama dengan kolom nama_petugas?*/ BEGIN FOR X IN c_nama LOOP DBMS_OUTPUT.PUT_LINE (c_nama%ROWCOUNT ||'Daftar Nama Petugas : ' || x.nama_petugas); END LOOP; END;
Ref Cursor
Kita dapat menggunakan ref cursor untuk mengembalikan nilai dalam bentuk recordset/cursor di store procedure.
Ada 2 tipe ref cursor :
- Strong ref cursor : tipe data dan panjangnya harus diketahui saat compile
- Weak ref cursor : tipe data dan panjangnya tidak dibutuhkan saat compile
Contoh :
declare type r_cursor IS REF CURSOR; c_emp r_cursor; en emp%rowtype; begin open c_emp FOR SELECT * FROM emp; loop fetch c_emp INTO en; exit when c_emp%notfound; dbms_output.put_line(c_emp%rowcount ||'. '||en.nama); end loop; close c_emp; end; declare type r_cursor IS REF CURSOR; c_emp r_cursor; en emp%rowtype; begin open c_emp FOR SELECT * FROM emp; loop fetch c_emp INTO en; exit when c_emp%notfound; dbms_output.put_line(c_emp%rowcount ||'. '||en.nama); end loop; close c_emp; end;
Menggunakan ref cursor di dalam loop
Contoh :
declare type r_cursor IS REF CURSOR; c_emp r_cursor; type rec_emp IS record ( deptno varchar2(20), nama number(6) ); er rec_emp; begin FOR i IN (SELECT deptno,lokasi FROM location) loop open c_emp FOR SELECT * FROM emp WHERE deptno = i.deptno; dbms_output.put_line(i.lokasi); dbms_output.put_line('--------------'); loop fetch c_emp INTO er; exit when c_emp%notfound; dbms_output.put_line(er.name || ' - ' || er.sal); end loop; close c_emp; end loop; end;
pada variabel ‘i’ tersedia informasi pada tabel location (deptno, lokasi).
Persamaan dan perbedaan antara cursor dan ref cursor :
Persamaan :
- Untuk menerima hasil query yang jumlah barisnya lebih dari 1 baris
- Memungkinkan untuk melakukan proses yang lebih kompleks untuk setiap record
Perbedaan :
- Sebuah ref cursor dapat diasosiasikan dengan lebih dari 1 klausa SELECT saat run-time. Sebelum klausa SELECT baru, cursor sebelumnya harus ditutup dulu.





Saya mau tanya kalo mau buat procedure yang return Ref cursor bagaimana?
Sekalian contoh ngecek apakah sudah berhasil atao blom ditunggu ya
saya akan memberikan beberapa contoh cara pembuatan procedure yang mengembalikan nilai berupa ref cursor :
–create table pegawai
CREATE TABLE PEGAWAI (
NIP VARCHAR2(9) PRIMARY KEY,
NAMA VARCHAR2(50)
);
–procedure dengan ref cursor di dalamnya
CREATE OR REPLACE PROCEDURE test_pegawai
AS
TYPE rc IS REF CURSOR;
v_cursor rc;
v_data pegawai%rowtype;
BEGIN
OPEN v_cursor FOR SELECT * FROM PEGAWAI;
LOOP
FETCH v_cursor INTO v_data;
EXIT WHEN v_cursor%notfound;
DBMS_OUTPUT.PUT_LINE(v_cursor%ROWCOUNT ||’. Pegawai dengan NIP ‘ ||v_data.NIP ||’ bernama ‘||v_data.NAMA);
END LOOP;
CLOSE v_cursor;
END test_pegawai;
– cara memanggil procedure test_pegawai
EXECUTE test_pegawai;
Nah bagaimana jika ref cursor itu ada di dalam package specification?
–create package
CREATE OR REPLACE PACKAGE EMPLOYEE
AS
TYPE rc IS REF CURSOR RETURN PEGAWAI%ROWTYPE;
END EMPLOYEE;
–create procedure yang memanggil ref cursor. ref cursor dapat dipanggil melalui package body atau procedure yang terpisah
CREATE OR REPLACE PROCEDURE call_employee (ref_c OUT EMPLOYEE.RC)
AS
v_data PEGAWAI%ROWTYPE;
BEGIN
OPEN ref_c FOR SELECT * FROM PEGAWAI;
LOOP
FETCH ref_c INTO v_data;
EXIT WHEN ref_c%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (ref_c%ROWCOUNT ||’. Pegawai dengan NIP ‘ ||v_data.NIP ||’ bernama ‘ ||v_data.NAMA);
END LOOP;
CLOSE ref_c;
END call_employee;
–cara memanggil procedure call_employee. Ingat procedure yang mempunyai atribut OUT atau IN OUT harus dipanggil melalui blok PL/SQL lain
DECLARE
c EMPLOYEE.RC;
BEGIN
call_employee(c);
END;
Nah selamat mencoba ^^
terima kasih onlypie, sangat membantu