Ik zou hiervoor geen expliciete cursor gebruiken. Steve F. raadt mensen niet langer aan om expliciete cursors te gebruiken wanneer een impliciete cursor zou kunnen worden gebruikt.
De methode met count(*)
is onveilig. Als een andere sessie de rij verwijdert die aan de voorwaarde voldeed na de regel met de count(*)
, en voor de regel met de select ... into
, zal de code een uitzondering genereren die niet wordt afgehandeld.
De tweede versie van het originele bericht heeft dit probleem niet en heeft over het algemeen de voorkeur.
Dat gezegd hebbende, is er een kleine overhead bij het gebruik van de uitzondering, en als u 100% zeker weet dat de gegevens niet zullen veranderen, kunt u de count(*)
gebruiken , maar ik raad het af.
Ik heb deze benchmarks uitgevoerd op Oracle 10.2.0.1 op 32-bits Windows . Ik kijk alleen naar de verstreken tijd. Er zijn andere testharnassen die meer details kunnen geven (zoals het aantal vergrendelingen en het gebruikte geheugen).
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;
/