Ya, banyak orang mengikuti praktik buruk.
Gaya Buruk
Saya setuju dengan @Osy bahwa OPEN/FETCH/CLOSE menambahkan kode yang sama sekali tidak perlu. Saya akan melangkah lebih jauh, dan mengatakan bahwa Anda hampir tidak boleh menggunakan CURSOR
.
Pertama-tama, Anda biasanya ingin melakukan sebanyak mungkin dalam SQL biasa. Jika Anda perlu menggunakan PL/SQL, gunakan kursor implisit. Ini akan menghemat satu baris kode dan akan membantu Anda menjaga logika terkait lebih dekat.
Saya sangat percaya dalam menjaga unit kode individu sekecil mungkin. Sekilas, sepertinya CURSOR
dapat membantu Anda melakukan ini. Anda dapat mendefinisikan SQL Anda di atas di satu tempat, dan kemudian melakukan perulangan PL/SQL nanti.
Namun pada kenyataannya, lapisan tipuan ekstra itu hampir tidak pernah sepadan. Terkadang banyak logika dalam SQL, dan terkadang banyak logika dalam PL/SQL. Namun dalam praktiknya, jarang masuk akal untuk menempatkan banyak logika kompleks di keduanya. Kode Anda biasanya terlihat seperti ini:
for records in (<simple SQL>) loop
<complex PL/SQL>
end loop;
atau:
for records in
(
<complex SQL>
) loop
<simple PL/SQL>;
end loop;
Either way, salah satu bagian kode Anda akan sangat kecil. Kompleksitas pemisahan dua bagian kode itu lebih besar daripada kerumitan satu bagian kode yang lebih besar. (Tapi itu jelas pendapat saya.)
Kinerja Buruk
Ada implikasi kinerja yang signifikan dengan menggunakan OPEN/FETCH/CLOSE. Metode itu jauh lebih lambat daripada menggunakan kursor untuk loop atau kursor implisit.
Kompiler dapat secara otomatis menggunakan pengumpulan massal di beberapa loop for. Tapi, mengutip dari presentasi Oracle "Kinerja PL/SQL—Membongkar Mitos" , halaman 122:
Berikut ini contoh singkatnya:
--Sample data
create table t(a number, b number);
insert into t select level, level from dual connect by level <= 100000;
commit;
--OPEN/FETCH/CLOSE
--1.5 seconds
declare
cursor test_cur is
select a, b from t;
test_rec test_cur%rowtype;
counter number;
begin
open test_cur;
loop
fetch test_cur into test_rec;
exit when test_cur%notfound;
counter := counter + 1;
end loop;
close test_cur;
end;
/
--Implicit cursor
--0.2 seconds
declare
counter number;
begin
for test_rec in (select a, b from t) loop
counter := counter + 1;
end loop;
end;
/