Ich würde dafür keinen expliziten Cursor verwenden. Steve F. rät Leuten nicht mehr, explizite Cursor zu verwenden, wenn ein impliziter Cursor verwendet werden könnte.
Die Methode mit count(*)
ist unsicher. Wenn eine andere Sitzung die Zeile löscht, die die Bedingung nach der Zeile mit count(*)
erfüllt hat , und vor der Zeile mit dem select ... into
, löst der Code eine Ausnahme aus, die nicht behandelt wird.
Die zweite Version des ursprünglichen Beitrags hat dieses Problem nicht und wird im Allgemeinen bevorzugt.
Allerdings gibt es bei der Verwendung der Ausnahme einen geringen Mehraufwand, und wenn Sie sich zu 100 % sicher sind, dass sich die Daten nicht ändern, können Sie count(*)
verwenden , aber ich rate davon ab.
Ich habe diese Benchmarks auf Oracle 10.2.0.1 ausgeführt auf 32-Bit-Windows . Ich schaue nur auf die verstrichene Zeit. Es gibt andere Testumgebungen, die weitere Details liefern können (z. B. Latch-Zähler und verwendeter Speicher).
SQL>create table t (NEEDED_FIELD number, COND number);
SQL>insert into t (NEEDED_FIELD, cond) values (1, 0);
declare
otherVar number;
cnt number;
begin
for i in 1 .. 50000 loop
select count(*) into cnt from t where cond = 1;
if (cnt = 1) then
select NEEDED_FIELD INTO otherVar from t where cond = 1;
else
otherVar := 0;
end if;
end loop;
end;
/
declare
otherVar number;
begin
for i in 1 .. 50000 loop
begin
select NEEDED_FIELD INTO otherVar from t where cond = 1;
exception
when no_data_found then
otherVar := 0;
end;
end loop;
end;
/