sql >> Databáze >  >> RDS >> Oracle

Je špatný postup používat instrukce EXIT WHEN při procházení CURSORů v Oracle?

Ano, mnoho lidí dodržuje špatnou praxi.

Špatný styl

Souhlasím s @Osy, že OPEN/FETCH/CLOSE přidává zcela zbytečný kód. Šel bych ještě dále a řekl bych, že byste téměř nikdy neměli používat CURSOR .

Za prvé, normálně chcete udělat co nejvíce v prostém SQL. Pokud potřebujete použít PL/SQL, použijte implicitní kurzor. Ušetří vám to řádek kódu a pomůže vám udržet související logiku blíže pohromadě.

Jsem pevně zastáncem toho, aby byly jednotlivé jednotky kódu co nejmenší. Na první pohled to vypadá jako CURSOR vám s tím může pomoci. Své SQL můžete definovat nahoře na jednom místě a poté opakování PL/SQL provést později.

Ale ve skutečnosti ta další vrstva nepřímosti téměř nikdy nestojí za to. Někdy je hodně logiky v SQL a někdy je hodně logiky v PL/SQL. Ale v praxi má málokdy smysl vkládat do obou hodně složitou logiku. Váš kód obvykle nakonec vypadá takto:

for records in (<simple SQL>) loop
    <complex PL/SQL>
end loop;

nebo:

for records in
(
    <complex SQL>
) loop
    <simple PL/SQL>;
end loop;

V každém případě bude jedna z vašich sekcí kódu velmi malá. Složitost oddělení těchto dvou částí kódu je větší než složitost větší jediné části kódu. (Ale to je samozřejmě můj názor.)

Špatný výkon

Použití OPEN/FETCH/CLOSE má významné dopady na výkon. Tato metoda je mnohem pomalejší než pomocí kurzoru pro smyčku nebo implicitního kurzoru.

Kompilátor může automaticky použít hromadné shromažďování v některých smyčkách for. Ale abych citoval z prezentace Oracle "Výkon PL/SQL — Odhalení mýtů" , strana 122:

Zde je rychlý příklad:

--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;
/


  1. mysql agregační UDF (uživatelem definovaná funkce) v C

  2. Je možné vybrat data serveru SQL pomocí pořadové pozice sloupce

  3. Jak získat celočíselný výstup z dotazu SQL

  4. Seřadit výběr řádku podle více sloupců