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 |