Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Czy używanie instrukcji EXIT WHEN podczas przechodzenia przez kursory w Oracle jest złą praktyką?

Tak, wiele osób stosuje złą praktykę.

Zły styl

Zgadzam się z @Osy, że OPEN/FETCH/CLOSE dodaje zupełnie niepotrzebny kod. Pójdę jeszcze dalej i powiem, że prawie nigdy nie należy używać CURSOR .

Po pierwsze, zwykle chcesz zrobić jak najwięcej w zwykłym SQL. Jeśli musisz użyć PL/SQL, użyj niejawnego kursora. Zaoszczędzi ci to linijki kodu i pomoże ci utrzymać powiązaną logikę bliżej siebie.

Mocno wierzę w to, aby poszczególne jednostki kodu były jak najmniejsze. Na pierwszy rzut oka wygląda na CURSOR może ci w tym pomóc. Możesz zdefiniować swój SQL od góry w jednym miejscu, a następnie wykonać pętlę PL/SQL później.

Ale w rzeczywistości ta dodatkowa warstwa pośredniości prawie nigdy nie jest tego warta. Czasami dużo logiki jest w SQL, a czasami dużo logiki jest w PL/SQL. Ale w praktyce rzadko ma sens umieszczanie w obu bardzo złożonej logice. Twój kod zwykle wygląda jak jeden z tych:

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

lub:

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

Tak czy inaczej, jedna z sekcji twojego kodu będzie bardzo mała. Złożoność rozdzielenia tych dwóch sekcji kodu jest większa niż złożoność większej, pojedynczej sekcji kodu. (Ale to oczywiście moja opinia.)

Zła wydajność

Korzystanie z funkcji OPEN/FETCH/CLOSE ma poważne konsekwencje dla wydajności. Ta metoda jest znacznie wolniejsza niż używanie kursora pętli lub niejawnego kursora.

Kompilator może automatycznie używać zbierania zbiorczego w niektórych pętlach for. Ale, cytując prezentację Oracle, "Wydajność PL/SQL — obalanie mitów" , strona 122:

Oto krótki przykład:

--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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Proszę o podanie kodu ceny tylko wtedy, gdy wpisz :=E

  2. grant na tworzenie synonimów na innym schemacie (Oracle)

  3. Błędy podczas instalacji jdk 1.7 w linuksie

  4. Procedura Oracle PL/SQL działa wolniej niż SQL

  5. Oracle scala stałe w jedną tabelę