Oracle
 sql >> база данни >  >> RDS >> Oracle

Лоша практика ли е да се използва инструкция EXIT WHEN, когато преминавате през CURSOR в Oracle?

Да, много хора следват лоша практика.

Лош стил

Съгласен съм с @Osy, че OPEN/FETCH/CLOSE добавя напълно ненужен код. Бих отишъл дори по-далеч и бих казал, че почти никога не трябва да използвате CURSOR .

На първо място, обикновено искате да правите възможно най-много с обикновен SQL. Ако трябва да използвате PL/SQL, използвайте скрит курсор. Това ще ви спести ред код и ще ви помогне да поддържате свързаната логика по-близо една до друга.

Силно вярвам в поддържането на възможно най-малки отделни единици код. На пръв поглед изглежда като CURSOR може да ви помогне да направите това. Можете да дефинирате своя SQL най-отгоре на едно място и след това да извършите PL/SQL цикъла по-късно.

Но в действителност този допълнителен слой индиректност почти никога не си заслужава. Понякога много логика е в SQL, а понякога много логика е в PL/SQL. Но на практика рядко има смисъл да се влага много сложна логика и в двете. Вашият код обикновено изглежда като един от следните:

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

или:

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

Така или иначе, една от секциите на вашия код ще бъде много малка. Сложността на разделянето на тези две секции от код е по-голяма от сложността на по-голяма, единична секция от код. (Но това очевидно е моето мнение.)

Лоша производителност

Използването на OPEN/FETCH/CLOSE има значителни последици за производителността. Този метод е много по-бавен отколкото да използвате курсор за цикъл или скрит курсор.

Компилаторът може автоматично да използва групово събиране в някои for цикли. Но цитирам от презентацията на Oracle "PL/SQL производителност—Развенчаване на митовете" , страница 122:

Ето бърз пример:

--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. Обекти на стил на променлива таблица в Oracle

  2. Алтернатива на sql сървър TOP в oracle

  3. Проблем с NHibernate TransactionScope с Oracle 11g

  4. Как да премахнете водещите нули от датите в Oracle

  5. PL/SQL пренаписва конкатенирана заявка с клауза „IN“.