Теория для лабораторной работы №5 - "PL/SQL – курсоры и хранимые процедуры", страница 5

 

OPEN c1;

LOOP

   FETCH c1 INTO my_record;

   EXIT WHEN c1%NOTFOUND;

   -- обработать запись

END LOOP;

 

Запрос может ссылаться на переменные PL/SQL в их области видимости. Однако, все переменные в запросе вычисляются только при открытии курсора. В следующем примере, каждое полученное жалование умножается на 2, даже при том, что коэффициент увеличивается при каждой выборке:

 

DECLARE

   my_sal emp.sal%TYPE;

   my_job emp.job%TYPE;

   factor INTEGER := 2;

   CURSOR c1 IS SELECT factor*sal FROM emp WHERE job = my_job;

BEGIN

   ...

   OPEN c1;  -- here factor equals 2

   LOOP

      FETCH c1 INTO my_sal;

      EXIT WHEN c1%NOTFOUND;

      ...

      factor := factor + 1;  -- does not affect FETCH

   END LOOP;

END;

 

Для изменения активного множества или значения переменных в запросе, нужно закрыть в вновь открыть курсор с входными переменными установленными в их новые значения.

Однако, можно использовать различные списки при INTO при разных выборках с одним и тем же курсором. каждая выборка получает другую строку и присваивает значения целевым переменным как показывает следующий пример:

 

DECLARE

   CURSOR c1 IS SELECT ename FROM emp;

   name1 emp.ename%TYPE;

   name2 emp.ename%TYPE;

   name3 emp.ename%TYPE;

BEGIN

   OPEN c1;

   FETCH c1 INTO name1;  -- this fetches first row

   FETCH c1 INTO name2;  -- this fetches second row

   FETCH c1 INTO name3;  -- this fetches third row

 

   ...

   CLOSE c1;

END;

 

Важные пункты

Если выбрать значение за последней строкой активного множества, значения целевых переменных неопределены.

В конечном счете, оператор FETCH не должен возвращать строку, поэтому когда это случается не вызывается исключение. Фактически, оператор FETCH  может сбоить много раз не вызывая исключения. Значит, нужно включить оператор EXIT WHEN, если поместить оператор FETCH в простой цикл. Иначе цикл будет выполняться бесконечно.