PL/SQL - DAY 2

BUMSOO·2024년 7월 3일

[문제 1]

화면과 같이 출력하는 익명 블록 구조 프로그램을 작성해주세요.
급여는 15200입니다.
별은 15개를 받았습니다.
★★★★★★★★★★★★★★★

<풀이>

DECLARE
    v_sal number := 15200 ;
BEGIN 
    dbms_output.put_line('급여는 ' || v_sal || ' 입니다.');
    dbms_output.put_line('별은 ' || trunc(v_sal/1000) || '개를 받았습니다.');
    dbms_output.put_line(lpad('★',v_sal/1000, '★'));
END;
/

조건제어문

  • PL/SQL에서 조건에 따라 선별적으로 작업을 수행할 수 있다.
  • boolean data type(true, false) - pl/sql에만 있는 타입
  • 조건제어문에서 NULL은 FALSE의 개념, IF NULL은 END IF로 끝나버린다.

조건이 TRUE 일 경우 수행하는 로직

IF 조건 THEN
	참일때 수행하는 로직;
END IF;

조건이 TRUE 또는 FALSE일 경우 수행하는 로직

IF 조건 THEN 
	참일때 수행하는 로직;
ELSE
	거짓일때 수행하는 로직;
END IF;

조건이 TRUE 또는 FALSE일때 다시 조건을 평가해야 하는 경우 수행하는 로직

IF 조건 THEN
	참일때 수행하는 로직;
ELSIF 조건 THEN
	참일때 수행하는 로직;
ELSIF 조건 THEN
	참일때 수행하는 로직;
....
ELSE 
	거짓일때 수행하는 로직;
END IF;

비교연산자

=, >, >=, <, <=, <>, !=, ^=

논리연산자

NOT, AND, OR

기타 비교연산자

BETWEEN AND, IN, LIKE

NULL 연산자

IS NULL, IS NOT NULL

DECLARE
    v_a number := 10;
    v_b number := 5;
BEGIN
    IF v_a >= v_b THEN 
        dbms_output.put_line(v_a - v_b);
    ELSE 
        IF v_a < v_b THEN
            dbms_output.put_line(v_b - v_a);
        END IF;
    END IF;
END;
/

[문제2]

IF문을 이용해서 계산이 수행되도록 해주세요.

v_sal : 10000
v_comm : NULL
v_annual_salary : v_sal * 12 + v_sal * v_comm * 12

DECLARE
    v_sal number := 10000;
    v_comm number;
    v_annual_salary number;
BEGIN
    IF v_comm IS NULL THEN
        v_annual_salary := v_sal * 12;
    ELSE 
        v_annual_salary := v_sal * 12 + v_sal*v_comm*12;
    END IF;
END;
/

CASE 표현식

  • 조건을 평가해서 값을 반환해준다
  • CASE로 시작해서 END로 끝난다.

- CASE표현식

DECLARE
    v_grade char(1) := upper('a');
    v_appraisal varchar2(30);
BEGIN
    v_appraisal := CASE WHEN v_grade = 'A' THEN '참잘했어요'
                        WHEN v_grade = 'B' THEN '잘했어요'
                        WHEN v_grade = 'C' THEN '다음에 잘해요'
                        ELSE '니가 사람이야!!!'  END;
    dbms_output.put_line('등급은 ' || v_grade || ' 평가는 ' || v_appraisal);
END;
/

- IF문으로 표현

DECLARE
    v_grade char(1) := upper('a');
    v_appraisal varchar2(30);
BEGIN
    IF v_grade = 'A' THEN
        v_appraisal := '참잘했어요';
    ELSIF v_grade = 'B' THEN
        v_appraisal := '잘했어요';
    ELSIF v_grade = 'C' THEN
        v_appraisal := '다음에 잘해요';
    ELSE
        v_appraisal := '니가 사람이야!!!';
    END IF;

    dbms_output.put_line('등급은 ' || v_grade || ' 평가는 ' || v_appraisal);
END;
/

CASE문

  • 조건을 평가하여 작업(SQL, 로직구현)을 수행한다.
  • CASE로 시작해서 END CASE로 끝난다.
  • PL/SQL에서만 구현 가능
DECLARE
    v_grade char(1) := upper('a');
    v_appraisal varchar2(30);
BEGIN
    CASE
        WHEN v_grade = 'A' THEN
            v_appraisal := '참잘했어요';
        WHEN v_grade = 'B' THEN
            v_appraisal := '잘했어요';
        WHEN v_grade in('C','D') THEN
            v_appraisal := '다음에 잘해요';
        ELSE
            v_appraisal := '니가 사람이야!!!';
    END CASE;

    dbms_output.put_line('등급은 ' || v_grade || ' 평가는 ' || v_appraisal);
END;
/

반복문

반복문(LOOP)은 명령문이나 명령문 시퀀스를 여러번 반복한다.

LOOP 문(기본 LOOP 문)

  • 조건이 없이 반복적인 작업 수행
  • 무한 반복한다.
  • EXIT문을 이용해서 반복문을 종료해야한다.

<기본문법>

LOOP
	문장...
    EXIT [WHEN 조건];
    /*
   	IF 조건 THEN
    	EXIT;
    END IF;
    */
END LOOP;

<활용>

DECLARE
    v_cnt number := 1;
BEGIN
    LOOP 
        dbms_output.put_line(v_cnt);
        IF v_cnt = 10 THEN
            EXIT;
        END IF;
        v_cnt := v_cnt +1 ;
    END LOOP;
END;
/

또는

DECLARE
    v_cnt number := 1;
BEGIN
    LOOP 
        dbms_output.put_line(v_cnt);
        EXIT WHEN v_cnt = 10;
        v_cnt := v_cnt +1 ;
    END LOOP;
END;
/

[문제3]

화면에 1~10까지 출력하는 프로그램을 작성해 주세요.
단, 4,8번은 출력하지 마세요.

<풀이>

DECLARE
    v_cnt number := 1;
BEGIN
    LOOP
        IF v_cnt not in (4,8) THEN 
            dbms_output.put_line(v_cnt);
        END IF;
        EXIT WHEN v_cnt = 10;
         v_cnt := v_cnt +1;
        
    END LOOP;
END;
/

<또 다른 풀이>

DECLARE 
    v_sal number := 1;
BEGIN
    LOOP
        IF mod(v_sal,4) = 0 THEN
            NULL;
        ELSE
            dbms_output.put_line(v_sal);
        END IF;
        
        EXIT WHEN v_sal = 10;
        v_sal := v_sal + 1;
    END LOOP;
END;
/

[문제4]

1부터 100까지의 합을 출력해주세요.

<풀이>

DECLARE
    v_cnt number := 1;
    v_sum number := 0;
BEGIN
    LOOP
        v_sum := v_sum + v_cnt;
        v_cnt := v_cnt +1;
        EXIT WHEN v_cnt = 101;
    
    END LOOP;
    dbms_output.put_line(v_sum);
END;
/

CONTINUE 문

루프구조에서 contitnue문을 만나는 순간 다음 반복으로 수행하는 문이다.

DECLARE 
    v_sal number := 1;
BEGIN
    LOOP
        IF mod(v_sal,4) = 0 THEN
            v_sal := v_sal +1;
            CONTINUE;
        ELSE
            dbms_output.put_line(v_sal);
        END IF;
        EXIT WHEN v_sal = 10;
        v_sal := v_sal + 1;
    END LOOP;
END;
/

WHILE LOOP 문

조건이 TRUE 동안 반복 작업을 수행하는 루프구조이다.

<기본 문법>

WHILE 조건 LOOP
	반복수행할 문장;
    ````
END LOOP;

<활용>

DECLARE
    v_cnt number := 1;
BEGIN
    WHILE v_cnt <= 10 LOOP
        dbms_output.put_line(v_cnt);
        v_cnt := v_cnt + 1;
    END LOOP;
END;
/

FOR LOOP 문

  • 반복 횟수를 알고 있을때 사용하는 루프문이다.
  • FOR LOOP문에서 사용되는 카운터 변수는 암시적으로 선언된다.
  • 카운터 변수는 할당 대상으로 사용할 수 없다.
  • 카운터 변수는 LOOP 문 안에서만 사용한다.
  • 카운터값이 null일 경우 오류발생
  • 카운터값은 숫자형만 가능하다.

<기본 문법>

FOR 카운터변수 IN [REVERSE]작은값..큰값 LOOP
	반복수행할 문장;
    ```
END LOOP;

<활용>

BEGIN
    FOR i IN 1..10 LOOP
        dbms_output.put_line(i);
        --i := i+1 -- 오류발생
    END LOOP;

END;
/

또는

DECLARE
    v_start number := 1;
    v_end number := 10;
BEGIN
    FOR i IN v_start..v_end LOOP
        dbms_output.put_line(i);
    END LOOP;

END;
/

<REVERSE(역순) 옵션>

DECLARE
    v_start number := 1;
    v_end number := 10;
BEGIN
    FOR i IN REVERSE v_start..v_end LOOP
        dbms_output.put_line(i);
    END LOOP;

END;
/

[18일차 후기]

요즘 비가 많이 왔는데 오늘은 비가 오지 않아 비오지 않는 날이 이렇게 행복하다라는걸 다시 한번 깨달으면서 시작한 하루였다. 오늘 크게보면 PL/SQL에서의 조건제어문,반복문 2개를 배웠다.
조건제어문에는 CASE표현식, IF 문, CASE문 이 있는데 상황에 따라 다르겠지만 조건을 수행해 값만 돌려주면 되면 CASE표현식을 쓰는게 좋겠지만, 그게 아닌 결과값에 SQL문을 삽입하거나 로직구현을 하기 위해서는 IF문 or CASE문을 써야했다. IF문을 쓰면서 웃겼던 부분은 언어마다 IF와 ELSE를 쓰는건 똑같은데 중간에 다른조건 IF문을 쓰는건 다 다르다는점이었다. java같은 경우 else if, python은 elif 인데 PL/SQL은 애매하게 else if 와 elif를 섞어놓은 elsif 를 사용한다.그냥 다 하나로 통일하면 안될까... 오후에는 반복문을 배웠는데 역시 PL/SQL도 다른언어들과 비슷하게 while loop, for loop, 무한 loop가 있었다.오늘 가장 당황했던 시간이 이때 생겼는데, 강사님께서 문제를 내주셨는데 반복문과 조건문을 같이 사용해 풀어야 하는 문제였다. 나는 긍정적으로 풀고 싶어 IF v_cnt in (4,8) THEN 이면 넘어가는 문장을 짜고싶었다. 근대 여기서 그냥 넘어갈라면 어떻게 해야할지 몰라 멘붕이 와서 문제를 풀지 못하였다. 강사님이 나중에 같이 풀이를 하면 알려주신 방법은 바로 NULL;을 사용하는 것였다. 그럼 수행하지 않고 다음 작업을 수행한다. while loop랑 무한 loop는 기존에 배운것과 비슷했는데,for loop는 모양은 비슷한데 디테일적인 부분이 다른 프로그램들의 for 문에 비해 다소 부족한 부분이 있었다.
우선 PL/SQL의 FOR 카운터변수 IN 카운터값 LOOP 에서 카운터 값은 무조건 숫자 범위로만 되어야 한다는 것이다. 게다가 그 숫자 범위를 주는 방식이 .. 이라고 하는데 너무 없어보인다.range가 그리울줄이야... 응용해보면 FOR i IN 1..10 LOOP 이런식으로 쓰는건데 PL/SQL에서의 FOR문은 정말 반복숫자용으로만 사용해야 할 것 같다.
이렇게 오늘 배운것들은 정리해 보았는데 느낀점은 언어 하나만 잘 배워놓으면 다른 언어를 학습할때 무조건 도움이 된다는 점이었다. 내가 만약 아예 프로그래밍에 대해 무지한 상태에서 오늘 수업을 들었다면... 좀 힘들었을 것 같긴 하다.

0개의 댓글