Ja, viele Leute folgen einer schlechten Praxis.
Schlechter Stil
Ich stimme @Osy zu, dass OPEN/FETCH/CLOSE völlig unnötigen Code hinzufügt. Ich würde sogar noch weiter gehen und sagen, dass Sie CURSOR
fast nie verwenden sollten .
Zunächst einmal möchten Sie normalerweise so viel wie möglich in einfachem SQL erledigen. Wenn Sie PL/SQL verwenden müssen, verwenden Sie einen impliziten Cursor. Es erspart Ihnen eine Codezeile und hilft Ihnen, die zugehörige Logik näher beieinander zu halten.
Ich glaube fest daran, einzelne Codeeinheiten so klein wie möglich zu halten. Auf den ersten Blick sieht es aus wie ein CURSOR
kann Ihnen dabei helfen. Sie können Ihr SQL oben an einer Stelle definieren und die PL/SQL-Schleife später ausführen.
Aber in Wirklichkeit lohnt sich diese zusätzliche indirekte Ebene fast nie. Manchmal steckt viel Logik in SQL und manchmal viel Logik in PL/SQL. Aber in der Praxis macht es selten Sinn, viel komplexe Logik in beide zu stecken. Ihr Code sieht normalerweise so aus:
for records in (<simple SQL>) loop
<complex PL/SQL>
end loop;
oder:
for records in
(
<complex SQL>
) loop
<simple PL/SQL>;
end loop;
In jedem Fall wird einer Ihrer Codeabschnitte sehr klein sein. Die Komplexität der Trennung dieser beiden Codeabschnitte ist größer als die Komplexität eines größeren einzelnen Codeabschnitts. (Aber das ist natürlich meine Meinung.)
Schlechte Leistung
Die Verwendung von OPEN/FETCH/CLOSE hat erhebliche Auswirkungen auf die Leistung. Diese Methode ist viel langsamer als einen Cursor für eine Schleife oder einen impliziten Cursor zu verwenden.
Der Compiler kann in einigen for-Schleifen automatisch die Massenerfassung verwenden. Aber um aus der Oracle-Präsentation zu zitieren "PL/SQL-Leistung – Mythen entlarven" , Seite 122:
Hier ist ein kurzes Beispiel:
--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;
/