본문 바로가기

Database/PL SQL

PL/SQL Tutorial - LOOP

LOOP

<<label>> LOOP
    statements;
END LOOP loop_label;

 While Loop, For Loop가 있으며 위 루프는 기본 루프이다. EXIT, EXIT WHEN이 없으면 무한 루프가 된다.

 

루프를 사용하기 좋을 때

- 본문을 한 번 이상 사용하고 싶을 때

- 몇 번이나 실행해야 하는지 모를 때

 

1) EXIT statement

원하는 때에 루프 밖으로 나가게 할 수 있다.

LOOP
    IF condition THEN
        EXIT;
    END IF;
END LOOP;

실제로 사용해본다.

DECLARE
  n_counter NUMBER := 0;
BEGIN
  LOOP
    n_counter := n_counter + 1;
    IF n_counter > 3 THEN
      EXIT;
    END IF;
    DBMS_OUTPUT.PUT_LINE( 'Inside loop: ' || n_counter )  ;
  END LOOP;
  -- control resumes here after EXIT
  DBMS_OUTPUT.PUT_LINE( 'After loop: ' || n_counter );
END;

익명 블록이 완료되었습니다.
Inside loop: 1
Inside loop: 2
Inside loop: 3
After loop: 4

n_counter를 정의해주고 n_counter = n_counter + 1 조건을 이용하여 3을 초과하면 빠져나오게 해 주었다. 

 

2) EXIT WHEN 

EXIT WHEN condition;

WHEN의 condition이 TRUE 일 때 루프를 종료한다.

DECLARE
  n_counter NUMBER := 0;
BEGIN
  LOOP
    n_counter := n_counter + 1;
    EXIT  WHEN n_counter > 3;
 
    DBMS_OUTPUT.PUT_LINE( 'Inside loop: ' || n_counter ) ;
  END LOOP;
  -- control resumes here after EXIT
  DBMS_OUTPUT.PUT_LINE( 'After loop: ' || n_counter );
END;

익명 블록이 완료되었습니다.
Inside loop: 1
Inside loop: 2
Inside loop: 3
After loop: 4

 

3) Nersted loops

 루프는 역시 중첩해야 제맛이다.

DECLARE
  n_i NUMBER := 0;
  n_j NUMBER := 0;
BEGIN
  << outer_loop >>
  LOOP
    n_i := n_i + 1;
    EXIT outer_loop WHEN n_i > 2;    
    DBMS_OUTPUT.PUT_LINE('Outer counter ' || n_i);
    -- reset inner counter
    n_j := 0;
    << inner_loop >> LOOP
      n_j := n_j + 1;
      EXIT inner_loop WHEN n_j > 3;
      DBMS_OUTPUT.PUT_LINE('   Inner counter ' || n_j);
    END LOOP inner_loop;
  END LOOP outer_loop;
END;

익명 블록이 완료되었습니다.
Outer counter 1
   Inner counter 1
   Inner counter 2
   Inner counter 3
Outer counter 2
   Inner counter 1
   Inner counter 2
   Inner counter 3

정해진 숫자에서부터가 아닌 지정된 횟수만큼 반복하는 루프를 FOR LOOP라고 한다.

FOR LOOP

FOR index IN lower_bound .. upper_bound
    LOOP 
    statements; 
END LOOP;

- INDEX는 루프안에서만 사용이 가능하며 루프 밖에서는 사용할 수 없다.

- 루프내부에서 INDEX의 값을 변화할 수 없다.

- index는 lower_bound에서 upper_bound로 변화하며 때문에 실수 형태여야 한다.

- lower_bound와 upper_bound 모두 loop가 한 번 돌아갈 때 설정되므로 값을 변경할 수 없다

예제를 살펴보자.

BEGIN
  FOR n_counter IN 1..5
  LOOP
    DBMS_OUTPUT.PUT_LINE( n_counter );
  END LOOP;
END;

익명 블록이 완료되었습니다.
1
2
3
4
5

n_counter가 1-5까지 변화하는 것을 알 수 있다. INDEX는 1씩 증가하여 사용처가 애매해 보이지만 다른 변수를 이용해서 원하는 값으로 변경할 수 있다.

DECLARE
  n_step PLS_INTEGER:=2;
BEGIN
  FOR n_counter IN 1..5 LOOP
    DBMS_OUTPUT.PUT_LINE(n_counter*n_step);
  END LOOP;
END;

익명 블록이 완료되었습니다.
2
4
6
8
10

다음 예제로 INDEX는 독자적인 변수라는 것을 확인할 수 있다.

DECLARE
  n_counter PLS_INTEGER := 10;
BEGIN
  FOR n_counter IN 1.. 5 loop
    DBMS_OUTPUT.PUT_LINE (n_counter);
  end loop;
  -- after the loop
  DBMS_OUTPUT.PUT_LINE (n_counter);
END; 

익명 블록이 완료되었습니다.
1
2
3
4
5
10

다음 예제는 왜 오류가 날까요?

BEGIN
  FOR n_index IN 1..3 loop
    DBMS_OUTPUT.PUT_LINE (n_index);
  END LOOP;
  -- referencing index after the loop
  DBMS_OUTPUT.PUT_LINE (n_index);
END;

오류 보고 -
ORA-06550: 줄 6, 열25:PLS-00201: 'N_INDEX' 식별자가 정의되어야 합니다

index를 loop 외부에서 사용하려고 했기 때문이다.

upper_bound부터 1씩 감소하는 loop를 만들고 싶다면 reversed를 사용하면 된다.

FOR index IN REVERSED lower_bound .. upper_bound
    LOOP 
    statements; 
END LOOP;

다른 조작없이도 upper_bound에서부터 시작하는 것을 볼 수 있다.

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

익명 블록이 완료되었습니다.
3
2
1

WHILE LOOP

WHILE condition
LOOP
    statements;
END LOOP;

condition은 boolean type으로 true, false, null 값을 가진다. 기본적으로 true일 때 반복하며 이 외의 값을 가졌을 때 분기한다.

simple한 예제를 보자.

DECLARE
  n_counter NUMBER := 1;
BEGIN
  WHILE n_counter < 6
  LOOP
    DBMS_OUTPUT.PUT_LINE( 'Counter : ' || n_counter );
    n_counter := n_counter + 1;
  END LOOP;
END;

익명 블록이 완료되었습니다.
Counter : 1
Counter : 2
Counter : 3
Counter : 4
Counter : 5

n_counter는 1에서부터 시작해서 스스로 1씩 더한다. 6이 넘으면 빠져나와(6<6은 false 이므로) loop가 종료된다.

나가는 지점을 따로 지정해줄 수도 있다.

DECLARE
   n_counter NUMBER := 1;
BEGIN
   WHILE n_counter <= 5
      LOOP
        DBMS_OUTPUT.PUT_LINE( 'Counter : ' || n_counter );
        n_counter := n_counter + 1;
        EXIT WHEN n_counter = 3;
      END LOOP;
   END;
   
익명 블록이 완료되었습니다.
Counter : 1
Counter : 2

exit when을 사용하면 true 값일 때 loop를 빠져나온다.

'Database > PL SQL' 카테고리의 다른 글

PL/SQL Tutorial - Exception handlers  (0) 2019.05.08
PL/SQL Tutorial - CONTINUE  (0) 2019.05.08
PL/SQL Tutorial - NULL  (0) 2019.05.07
PL/SQL Tutorial - GOTO  (0) 2019.05.07
PL/SQL Tutorial - CASE  (0) 2019.04.30