G-4370: Avoid using EXIT to stop loop processing unless you are in a basic loop.

Major

Maintainability

Reason

A numeric for loop as well as a while loop and a cursor for loop have defined loop boundaries. If you are not able to exit your loop using those loop boundaries, then a basic loop is the right loop to choose.

Example (bad)

DECLARE
   i INTEGER;
   co_min_value CONSTANT SIMPLE_INTEGER := 1;
   co_max_value CONSTANT SIMPLE_INTEGER := 10;
   co_increment CONSTANT SIMPLE_INTEGER := 1;
BEGIN
   i := co_min_value;
   <<while_loop>>
   WHILE (i <= co_max_value) 
   LOOP 
      i := i + co_increment; 
      EXIT while_loop WHEN i > co_max_value;
   END LOOP while_loop;

   <<basic_loop>>
   LOOP 
      EXIT basic_loop;
   END LOOP basic_loop;

   <<for_loop>>
   FOR i IN co_min_value..co_max_value
   LOOP 
      NULL;
      EXIT for_loop WHEN i = co_max_value;
   END LOOP for_loop;

   <<process_employees>>
   FOR r_employee IN (SELECT last_name
                        FROM employees)
   LOOP
      sys.dbms_output.put_line(r_employee.last_name);
      NULL; -- some processing
      EXIT process_employees;
   END LOOP process_employees;
END;
/

Example (good)

DECLARE
   i INTEGER;
   co_min_value CONSTANT SIMPLE_INTEGER := 1;
   co_max_value CONSTANT SIMPLE_INTEGER := 10;
   co_increment CONSTANT SIMPLE_INTEGER := 1;
BEGIN
   i := co_min_value;
   <<while_loop>>
   WHILE (i <= co_max_value) 
   LOOP 
      i := i + co_increment; 
   END LOOP while_loop;

   <<basic_loop>>
   LOOP 
      EXIT basic_loop;
   END LOOP basic_loop;

   <<for_loop>>
   FOR i IN co_min_value..co_max_value
   LOOP 
      sys.dbms_output.put_line(i);
   END LOOP for_loop;

   <<process_employees>>
   FOR r_employee IN (SELECT last_name
                        FROM employees)
   LOOP
      sys.dbms_output.put_line(r_employee.last_name); -- some processing
   END LOOP process_employees;
END;
/