LOOP Statements

Loop statements run the same statements iteratively with a series of different values.

A LOOP statement has three parts:
  1. An iterand, also known as a loop variable, to pass values from the loop header to the loop body
  2. Iteration controls to generate values for the loop
  3. A loop body run once for each value
loop_statement ::= [ iteration_scheme ] LOOP 
             loop_body 
END LOOP [ label ];

iteration_scheme ::= WHILE expression
                       | FOR iterator

The loop statements are:

  • Basic LOOP

  • FOR LOOP

  • Cursor FOR LOOP

  • WHILE LOOP

The statements that exit a loop are:

  • EXIT

  • EXIT WHEN

The statements that exit the current iteration of a loop are:

  • CONTINUE

  • CONTINUE WHEN

EXIT, EXIT WHEN, CONTINUE, and CONTINUE WHEN can appear anywhere inside a loop, but not outside a loop. Oracle recommends using these statements instead of the GOTO statement, which can exit a loop or the current iteration of a loop by transferring control to a statement outside the loop.

A raised exception also exits a loop.

LOOP statements can be labeled, and LOOP statements can be nested. Labels are recommended for nested loops to improve readability. You must ensure that the label in the END LOOP statement matches the label at the beginning of the same loop statement (the compiler does not check).

See Also:

Basic LOOP Statement

The basic LOOP statement has this structure.

With each iteration of the loop, the statements run and control returns to the top of the loop. To prevent an infinite loop, a statement or raised exception must exit the loop.

[ label ] LOOP
  statements
END LOOP [ label ];

See Also:

"Basic LOOP Statement"

FOR LOOP Statement Overview

The FOR LOOP statement runs one or more statements for each value of the loop index.

A FOR LOOP header specifies the iterator. The iterator specifies an iterand and the iteration controls. The iteration control provides a sequence of values to the iterand for access in the loop body. The loop body has the statements that are processed once for each value of the iterand.

The iteration controls available are :

Stepped Range An iteration control that generates a sequence of stepped numeric values. When step is not specified, the counting control is a stepped range of type pls integer with a step of one.

Single Expression An iteration control that evaluates a single expression.

Repeated Expression An iteration control that repeatedly evaluates a single expression.

Values Of An iteration control that generates all the values from a collection in sequence. The collection can be a vector valued expression, cursor, cursor variable, or dynamic SQL.

Indices Of An iteration control that generates all the indices from a collection in sequence. While all the collection types listed for values of are allowed, indices of is most useful when the collection is a vector variable.

Pairs Of An iteration control that generates all the index and value pairs from a collection. All of the collection types allowed for values of are allowed for pairs of. Pairs of iteration controls require two iterands.

Cursor An iteration control that generates all the records from a cursor, cursor variable, or dynamic SQL.

The FOR LOOP statement has this structure:

[ label ] for_loop_header 
  statements
END LOOP [ label ];

for_loop_header ::= FOR iterator LOOP

iterator ::= iterand_decl [, iterand_decl] IN iteration_ctl_seq 

iterand_decl  ::= pls_identifier [ MUTABLE | IMMUTABLE ] [ constrained_type ]          

iteration_ctl_seq ::= qual_iteration_ctl [,]...

qual_iteration_ctl ::= [ REVERSE ] iteration_control  pred_clause_seq

iteration_control ::= stepped_control 
                      | single_expression_control 
                      | values_of_control 
                      | indices_of_control 
                      | pairs_of_control  
                      | cursor_control 

pred_clause_seq ::= [ stopping_pred ] [ skipping_pred ]

stopping_pred ::= WHILE boolean_expression  

skipping_pred ::= WHEN boolean_expression 

stepped_control ::= lower_bound .. upper_bound [ BY step ]

single_expression_control ::= [ REPEAT ] expr

See Also:

"FOR LOOP Statement" for more information about syntax and semantics

FOR LOOP Iterand

The index or iterand of a FOR LOOP statement is implicitly or explicitly declared as a variable that is local to the loop.

The statements in the loop can read the value of the iterand, but cannot change it. Statements outside the loop cannot reference the iterand. After the FOR LOOP statement runs, the iterand is undefined. A loop iterand is sometimes called a loop counter.

Example 5-10 FOR LOOP Statement Tries to Change Index Value

In this example, the FOR LOOP statement tries to change the value of its index, causing an error.

BEGIN
  FOR i IN 1..3 LOOP
    IF i < 3 THEN
      DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
    ELSE
      i := 2;
    END IF;
  END LOOP;
END;
/

Result:

       i := 2;
       *
PLS-00363: expression 'I' cannot be used as an assignment target
ORA-06550: line 6, column 8:
PL/SQL: Statement ignored

Example 5-11 Outside Statement References FOR LOOP Statement Index

In this example, a statement outside the FOR LOOP statement references the loop index, causing an error.

BEGIN
  FOR i IN 1..3 LOOP
    DBMS_OUTPUT.PUT_LINE ('Inside loop, i is ' || TO_CHAR(i));
  END LOOP;
  
  DBMS_OUTPUT.PUT_LINE ('Outside loop, i is ' || TO_CHAR(i));
END;
/ 

Result:

  DBMS_OUTPUT.PUT_LINE ('Outside loop, i is ' || TO_CHAR(i));
                                                         *
PLS-00201: identifier 'I' must be declared
ORA-06550: line 6, column 3:
PL/SQL: Statement ignored

Example 5-12 FOR LOOP Statement Index with Same Name as Variable

If the index of a FOR LOOP statement has the same name as a variable declared in an enclosing block, the local implicit declaration hides the other declaration, as this example shows.

DECLARE
  i NUMBER := 5;
BEGIN
  FOR i IN 1..3 LOOP
    DBMS_OUTPUT.PUT_LINE ('Inside loop, i is ' || TO_CHAR(i));
  END LOOP;
  
  DBMS_OUTPUT.PUT_LINE ('Outside loop, i is ' || TO_CHAR(i));
END;
/

Result:

Inside loop, i is 1
Inside loop, i is 2
Inside loop, i is 3
Outside loop, i is 5

Example 5-13 FOR LOOP Statement References Variable with Same Name as Index

This example shows how to change Example 5-12 to allow the statement inside the loop to reference the variable declared in the enclosing block.

<<main>>  -- Label block.
DECLARE
  i NUMBER := 5;
BEGIN
  FOR i IN 1..3 LOOP
    DBMS_OUTPUT.PUT_LINE (
      'local: ' || TO_CHAR(i) || ', global: ' ||
      TO_CHAR(main.i)  -- Qualify reference with block label.
    );
  END LOOP;
END main;
/

Result:

local: 1, global: 5
local: 2, global: 5
local: 3, global: 5

Example 5-14 Nested FOR LOOP Statements with Same Index Name

In this example, the indexes of the nested FOR LOOP statements have the same name. The inner loop references the index of the outer loop by qualifying the reference with the label of the outer loop. For clarity only, the inner loop also qualifies the reference to its own index with its own label.

BEGIN
  <<outer_loop>>
  FOR i IN 1..3 LOOP
    <<inner_loop>>
    FOR i IN 1..3 LOOP
      IF outer_loop.i = 2 THEN
        DBMS_OUTPUT.PUT_LINE
          ('outer: ' || TO_CHAR(outer_loop.i) || ' inner: '
           || TO_CHAR(inner_loop.i));
      END IF;
    END LOOP inner_loop;
  END LOOP outer_loop;
END;
/

Result:

outer: 2 inner: 1
outer: 2 inner: 2
outer: 2 inner: 3

Iterand Mutability

The mutability property of an iterand determines whether or not it can be assigned in the loop body.

If all iteration controls specified in an iterator are cursor controls, the iterand is mutable by default. Otherwise, the iterand is immutable. The default mutability property of an iterand can be changed in the iterand declaration by specifying the MUTABLE or IMMUTABLE keyword after the iterand variable.

Considerations when declaring an iterand mutable:

  • Any modification to the iterand for values of iteration control or the values iterand for a pairs of iteration control will not affect the sequence of values produced by that iteration control.
  • Any modification to the iterand for stepped range iteration control or repeated single expression iteration control will likely affect the behaviour of that control and the sequence of values it produces.
  • When the PL/SQL compiler can determine that making an iterand mutable may adversely affect runtime performance, it may report a warning.

Multiple Iteration Controls

Multiple iteration controls may be chained together by separating them with commas.

Each iteration control has a set of controlling expressions (some controls have none) that are evaluated once when the control starts. Evaluation of these expressions or conversion of the evaluated values to the iterand type may raise exceptions. In such cases, the loop is abandoned and normal exception handling occurs. The iterand is accessible in the list of iteration controls. It is initially set to the default value for its type. If that type has a not null constraint, any reference to the iterand in the controlling expressions for the first iteration control will produce a semantic error because the iterand cannot be implicitly initialized. When an iteration control is exhausted, the iterand contains the final value assigned to it while processing that iteration control and execution advances to the next iteration control. If no values are assigned to the iterand by an iteration control, it retains the value it had prior to the start of that iteration control. If the final value of a mutable iterand is modified in the loop body, that modified value will be visible when evaluating the control expressions from the following iteration control.

Expanding Multiple Iteration Controls Into PL/SQL

The first iteration control is initialized. The loop for the first iteration control is evaluated. The controlling expressions from the next iteration control is evaluated. The loop for the second iteration control is evaluated. Each iteration control and loop is evaluated in turn until there are no more iteration controls.

Example 5-15 Using Multiple Iteration Controls

This example shows the loop variable i taking the value three iteration controls in succession. The value of the iterator is printed for demonstration purpose. It shows that when a loop control is exhausted, the next iteration control begins. When the last iteration control is exhausted, the loop is complete.

DECLARE
   i PLS_INTEGER;
BEGIN
   FOR i IN 1..3, REVERSE i+1..i+10, 51..55 LOOP
      DBMS_OUTPUT.PUT_LINE(i);
   END LOOP;
END;
/
Result:
1
2
3
13
12
11
10
9
8
7
6
5
4
51
52
53
54
55

Stepped Range Iteration Controls

Stepped range iteration controls generate a sequence of numeric values.

Controlling expressions are the lower bound, upper bound, and step.

stepped_control ::= [ REVERSE ] lower_bound..upper_bound [ BY step ]
lower_bound ::= numeric_expression
upper_bound ::= numeric_expression
step ::= numeric_expression

Expanding Stepped Range Iteration Controls Into PL/SQL

When the iteration control is initialized, each controlling expression is evaluated and converted to the type of the iterand. Step must have a strictly positive numeric value. If any exception occurs while evaluating the controlling expressions, the loop is abandoned and normal exception handling occurs. When no step is specified, its value is one. The values generated by a stepped range iteration control go from lower bound to upper bound by step. When REVERSE is specified the values are decremented from the upper bound to lower bound by step. If the iterand has a floating point type, some combinations of loop control values may create an infinite loop because of rounding errors. No semantic or dynamic analysis will report this. When the iterand is mutable and is modified in the loop body, the modified value is used for the increment and loop exhaustion test in the next iterand update. This may change the sequence of values processed by the loop.

Example 5-16 FOR LOOP Statements Range Iteration Control

In this example, the iterand i has a lower_bound of 1 and an upper_bound of 3. The loop prints the numbers from 1 to 3.

BEGIN
  FOR i IN 1..3 LOOP
     DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;
END;
/

Result:

1
2
3

Example 5-17 Reverse FOR LOOP Statements Range Iteration Control

The FOR LOOP statement in this example prints the numbers from 3 to 1. The loop variable i is implicitly declared as a PLS_INTEGER (the default for counting and indexing loops).

BEGIN
   FOR i IN REVERSE 1..3 LOOP
      DBMS_OUTPUT.PUT_LINE (i);
   END LOOP;
END;
/ 

Result:

3
2
1

Example 5-18 Stepped Range Iteration Controls

This example shows a loop variable n declared explicitly as a NUMBER(5,1). The increment for the counter is 0.5.
BEGIN
   FOR n NUMBER(5,1) IN 1.0 .. 3.0 BY 0.5 LOOP
      DBMS_OUTPUT.PUT_LINE(n);
   END LOOP;
END;
/
Result:
1
1.5
2
2.5
3

Example 5-19 STEP Clause in FOR LOOP Statement

In this example, the FOR LOOP effectively increments the index by five.

BEGIN
  FOR i IN 5..15 BY 5 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;
END;

Result:

5
10
15

Example 5-20 Simple Step Filter Using FOR LOOP Stepped Range Iterator

This example illustrates a simple step filter. This filter is used in signal processing and other reduction applications. The predicate specifies that every Kth element of the original collection is passed to the collection being created.

FOR i IN start..finish LOOP
   IF (i - start) MOD k = 0 THEN
      newcol(i) := col(i)
   END IF;
END LOOP;  
  

You can implement the step filter using a stepped range iterator.

FOR i IN start..finish BY k LOOP
   newcol(i) := col(i)
END LOOP;

You can implement the same filter by creating a new collection using a stepped iteration control embedded in a qualified expression.

newcol := col_t(FOR I IN start..finish BY k => col(i));

Single Expression Iteration Controls

A single expression iteration control generates a single value.

single_expression_control ::= [ REPEAT ] expr

A single expression iteration control has no controlling expressions.

When the iterand is mutable, changes made to it in the loop body will be seen when reevaluating the expression in the repeat form.

Expanding Single Expression Iteration Controls Into PL/SQL

The expression is evaluated, converted to the iterand type to create the next value. Any stopping predicate is evaluated. If it fails to evaluate to TRUE, the iteration control is exhausted. Any skipping predicate is evaluated. If it fails to evaluate to TRUE, skip the next step. Evaluate the loop body. If REPEAT is specified, evaluate the expression again. Otherwise, the iteration control is exhausted.

Example 5-21 Single Expression Iteration Control

This example shows the loop body being processed once.

BEGIN
   FOR i IN 1 LOOP
      DBMS_OUTPUT.PUT_LINE(i);
   END LOOP;
END;
/

Result:

1

This example shows the iterand starting with 1, then i*2 is evaluated repeatedly until the stopping predicate evaluates to true.

BEGIN
   FOR i IN 1, REPEAT i*2 WHILE i < 100 LOOP
      DBMS_OUTPUT.PUT_LINE(i);
   END LOOP;
END;
/

Result:

1
2
4
8
16
32
64

Collection Iteration Controls

VALUES OF, INDICES OF, and PAIRS OF iteration controls generate sequences of values for an iterand derived from a collection.

collection_iteration_control ::= values_of_control 
                                 | indices_of_control 
                                 | pairs_of_control 

values_of_control ::= VALUES OF expr 
                      | VALUES OF (cursor_object)
                      | VALUES OF (sql_statement)
                      | VALUES OF cursor_variable  
                      | VALUES OF (dynamic_sql) 

indices_of_control ::= INDICES OF expr 
                      | INDICES OF (cursor_object)
                      | INDICES OF (sql_statement)
                      | INDICES OF cursor_variable 
                      | INDICES OF (dynamic_sql)  

pairs_of_control ::= PAIRS OF expr 
                      | PAIRS OF (cursor_object) 
                      | PAIRS OF (sql_statement)
                      | PAIRS OF cursor_variable
                      | PAIRS OF (dynamic_sql) 
 

The collection itself is the controlling expression. The collection can be a vector value expression, a cursor object, cursor variable, or dynamic SQL. If a collection is null, it is treated as if it were defined and empty.

A cursor_object is an explicit PL/SQL cursor object. A sql_statement is an implicit PL/SQL cursor object created for a SQL statement specified directly in the iteration control. A cursor_variable is a PL/SQL REF CURSOR object.

When the iterand for a values of iteration control or the value iterand for a VALUES OF iteration control is modified in the loop body, those changes have no effect on the next value generated by the iteration control.

If the collection is modified in the loop body, behavior is unspecified. If a cursor variable is accessed other than through the iterand during execution of the loop body, the behavior is unspecified. Most INDICES OF iteration controls produce a numeric sequence unless the collection is a vector variable.

Expanding VALUES OF Iteration Controls into PL/SQL

The collection is evaluated and assigned to a vector. If the collection is empty, the iteration control is exhausted. A temporary hidden index is initialized with the index of the first element (or last element if REVERSE is specified). A value is fetched from the collection based on the temporary index to create the next value for the iterand. Any stopping predicate is evaluated. If it fails to evaluate to TRUE, the iteration control is exhausted. Any skipping predicate is evaluated. If it fails to evaluate to TRUE, skip the next step. Evaluate the loop body. Advance the index temporary to the index of the next element in the vector (previous element for REVERSE). Determine the next value and reiterate with each iterand value until the iteration control is exhausted.

Example 5-22 VALUES OF Iteration Control

This example prints the values from the collection vec: [11, 10, 34]. The iterand values of the iteration control variable i is the value of the first element in the vector, then the next element, and the last one.


DECLARE
   TYPE intvec_t IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
   vec intvec_t := intvec_t(3 => 10, 1 => 11, 100 => 34);
BEGIN
   FOR i IN VALUES OF vec LOOP
      DBMS_OUTPUT.PUT_LINE(i);
   END LOOP;
END;
/

Result:

11 10 34

Expanding INDICES OF Iteration Controls into PL/SQL

The collection is evaluated and assigned to a vector. If the collection is empty, the iteration control is exhausted. The next value for the iterand is determined (index of the first element or last element if REVERSE is specified). The next value is assigned to the iterand. Any stopping predicate is evaluated. If it fails to evaluate to TRUE, the iteration control is exhausted. Any skipping predicate is evaluated. If it fails to evaluate to TRUE, skip the next step. The loop body is evaluated. Advance the iterand to the next value which is the index of the next element in the vector (previous element for REVERSE). Reiterate with each iterand value (assigned the index of the next or previous element) until the iteration control is exhausted.

Example 5-23 INDICES OF Iteration Control

This example prints the indices of the collection vec : [1, 3, 100]. The iterand values of the iteration control variable i is the index of the first element in the vector, then the next element, and the last one.

DECLARE
   TYPE intvec_t IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
   vec intvec_t := intvec_t(3 => 10, 1 => 11, 100 => 34);
BEGIN
   FOR i IN INDICES OF vec LOOP 
       DBMS_OUTPUT.PUT_LINE(i);  
   END LOOP;
END;
/

Result:

1 3 100

Expanding PAIRS OF Iteration Controls into PL/SQL

The collection is evaluated and assigned to a vector. If the collection is empty, the iteration control is exhausted. The next index value for the iterand is determined (index of the first element or last element if REVERSE is specified). The next value of the element indexed by the next value is assigned to the iterand. Any stopping predicate is evaluated. If it fails to evaluate to TRUE, the iteration control is exhausted. Any skipping predicate is evaluated. If it fails to evaluate to TRUE, skip the next step. The loop body is evaluated. Advance the iterand to the next index value which is the index of the next element in the vector (previous element for REVERSE). Reiterate with each iterand value until the iteration control is exhausted.

Example 5-24 PAIRS OF Iteration Control

This example inverts a collection vec into a collection result and prints the resulting index value pairs (10 => 3, 11 => 1, 34 => 100).


DECLARE
   TYPE intvec_t IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
   vec  intvec_t := intvec_t(3 => 10, 1 => 11, 100 => 34);
   result intvec_t;
BEGIN
   result := intvec_t(FOR i,j IN PAIRS OF vec INDEX j => i);
   FOR i,j IN PAIRS OF result LOOP
      DBMS_OUTPUT.PUT_LINE(i || '=>'|| j);
   END LOOP;
END;
/
Result:

10=>3 11=>1 34=>100

Cursor Iteration Controls

Cursor iteration controls generate the sequence of records returned by an explicit or implicit cursor.

The cursor definition is the controlling expression. You cannot use REVERSE with a cursor iteration control.

cursor_iteration__control ::=  { cursor _object
                    | sql_statement
                    | cursor_variable
                    | dynamic_sql }

A cursor_object is an explicit PL/SQL cursor object. A sql_statement is an implicit PL/SQL cursor object created for a SQL statement specified directly in the iteration control. A cursor_variable is a PL/SQL REF CURSOR object. A cursor iteration control is equivalent to a VALUES OF iteration control whose collection is a cursor. When the iterand is modified in the loop body, it has no effect on the next value generated by the iteration control. When the collection is a cursor variable, it must be open when the iteration control is encountered or an exception will be raised. It remains open when the iteration control is exhausted. If the cursor variable is accessed other than through the iterand during execution of the loop body, the behavior is unspecified.

Expanding Cursor Iteration Controls Into PL/SQL

The cursor is evaluated to create a vector of iterands. If the vector is empty, the iteration control is exhausted. A value is fetched in the vector to create the next value for the iterand. Any stopping predicate is evaluated. If it fails to evaluate to TRUE, the iteration control is exhausted. Any skipping predicate is evaluated. If it fails to evaluate to TRUE, skip the next step. Evaluate the loop body. Reiterate the same with each iterand value fetched until the iteration control is exhausted.

Example 5-25 Cursor Iteration Controls

This example creates an associative array mapping of id to data from table t.
OPEN c FOR SELECT id, data FROM T;
FOR r rec_t IN c LOOP
   result(r.id) := r.data;
END LOOP;
CLOSE c;

Using Dynamic SQL in Iteration Controls

...
dynamic_sql ::= EXECUTE IMMEDIATE dynamic_sql_stmt [ using_clause ]

using_clause ::= USING [ [ IN ] (bind_argument [,])+ ]

Dynamic SQL may be used in a cursor or collection iteration control. Such a construct cannot provide a default type; if it is used as the first iteration control, an explicit type must be specified for the iterand (or for the value iterand for a pairs of control). The using_clause is the only clause allowed. No INTO or dynamic returning clauses may be used. If the specified SQL statement is a kind that cannot return any rows, a runtime error will be reported similar to that reported if a bulk collect into or into clause were specified on an ordinary EXECUTE IMMEDIATE statement.

Example 5-26 Using Dynamic SQL As An Iteration Control

This example shows the iteration control generates all the records from a dynamic SQL. It prints the last_name and employee_id of all employees having an employee_id less than 103. It executes the loop body when the stopping predicate is TRUE.

DECLARE
   cursor_str VARCHAR2(500) := 'SELECT last_name, employee_id FROM hr.employees ORDER BY last_name';
   TYPE rec_t IS RECORD (last_name VARCHAR2(25),
                         employee_id NUMBER);
BEGIN
   FOR r rec_t IN VALUES OF (EXECUTE IMMEDIATE cursor_str) WHEN r.employee_id < 103 LOOP
      DBMS_OUTPUT.PUT_LINE(r.last_name || ', ' || r.employee_id);
   END LOOP;
END;
/

Result:


Garcia, 102
King, 100
Yang, 101

Example 5-27 Using Dynamic SQL As An Iteration Control In a Qualified Expression

v := vec_rec_t( FOR r rec_t IN (EXECUTE IMMEDIATE query_var) SEQUENCE => r); 

Stopping and Skipping Predicate Clauses

A stopping predicate clause can cause the iteration control to be exhausted while a skipping predicate clause can cause the loop body to be skipped for some values.

The expressions in these predicate clauses are not controlling expressions.

A stopping predicate clause can cause the iteration control to be exhausted. The boolean_expression is evaluated at the beginning of each iteration of the loop. If it fails to evaluate to TRUE, the iteration control is exhausted.

A skipping predicate clause can cause the loop body to be skipped for some values. The boolean_expression is evaluated. If it fails to evaluate to TRUE, the iteration control skips to the next value.

pred_clause_seq ::= [stopping_pred] [skipping_pred]

stopping_pred ::= WHILE boolean_expression  

skipping_pred ::= WHEN boolean_expression 

Example 5-28 Using FOR LOOP Stopping Predicate Clause

This example shows an iteration control with a WHILE stopping predicate clause The iteration control is exhausted if the stopping predicate does not evaluate to TRUE.

BEGIN
   FOR power IN 1, REPEAT power*2 WHILE power <= 64 LOOP
      DBMS_OUTPUT.PUT_LINE(power);
   END LOOP;
END;
/

Result:

1
2
4
8
16
32
64

Example 5-29 Using FOR LOOP Skipping Predicate Clause

This example shows an iteration control with a WHEN skipping predicate clause. If the skipping predicate does not evaluate to TRUE, the iteration control skips to the next value.

BEGIN
   FOR power IN 2, REPEAT power*2 WHILE power <= 64 WHEN MOD(power, 32)= 0 LOOP
      DBMS_OUTPUT.PUT_LINE(power);
   END LOOP;
END;
/

Result:

2
32
64

WHILE LOOP Statement

The WHILE LOOP statement runs one or more statements while a condition is true.

It has this structure:

[ label ] WHILE condition LOOP
  statements
END LOOP [ label ];

If the condition is true, the statements run and control returns to the top of the loop, where condition is evaluated again. If the condition is not true, control transfers to the statement after the WHILE LOOP statement. To prevent an infinite loop, a statement inside the loop must make the condition false or null. For complete syntax, see "WHILE LOOP Statement".

An EXIT, EXIT WHEN, CONTINUE, or CONTINUE WHEN in the statements can cause the loop or the current iteration of the loop to end early.

Some languages have a LOOP UNTIL or REPEAT UNTIL structure, which tests a condition at the bottom of the loop instead of at the top, so that the statements run at least once. To simulate this structure in PL/SQL, use a basic LOOP statement with an EXIT WHEN statement:

LOOP
  statements
  EXIT WHEN condition;
END LOOP;