본문 바로가기
Study/중앙정보처리학원과정

28일차. PL/SQL

by 얏옹이 2022. 12. 1.
반응형

PL/SQL이란 기존 오라클 SQL 문법을 확장한 언어이다.

 

기존 SQL 문법에서 변수를 추가한다던지, 반복문을 이용한 반복 작업을 한다던지, 조건문을 이용하여 특정 조건을 만족했을때 수행한다던지 하는 일반 프로그래밍 언어에서 제공하는 많은 기능이 있다.

 

DB에 직접 컴파일되어 성능면에서도 우수하고, DB 관련처리를 할때 수많은 기능을 활용할수 있다는 장점이 있다.

 

PL/SQL은 크게 선언부, 실행부, 예외처리부로 나뉘는데 깊게 파고 들기 보다는 간단하지만 자주 사용되는 IF ELSIF

 

WHILE, FOR문을 살펴보려고 한다.

 

PL SQL의 기본 구조부터 살펴보자

 

--PL SQL

SET SERVEROUTPUT ON;
DECLARE
--변수 선언부
    num1 NUMBER := 0;
    num2 NUMBER;
    
begin
--실행부
    --Java에서 System.out.print와 동일한 콘솔 출력문
    dbms_output.put_line('졸립니다');
    dbms_output.put_line(num1);
    dbms_output.put_line(num2);
end;

 

SET SERVEROUTPUT ON은 기본적으로 PL/SQL은 결과를 출력해주지 않는다. 따라서 결과문을 보기 위해서는

 

출력을 해달라~ 라는 선언을 해줘야하는데 그것이 바로 이 문구이다. 

 

기본적으로 PL/SQL에서 변수선언할때는 Java와는 조금 다르게 = 로 선언해주는것이 아닌 := 로 선언해준다. 선언과 동시에 초기값을 정해줄수도 있고, 정해주지 않으면 기본 DEFAULT 값은 NULL이다. 

 

JAVA에서는 데이터 타입에따라 0이 들어간다던지, NULL이 들어간다던지 하는데 PL/SQL에서는 데이터 타입과 상관없이 모두 NULL이다.

 

따라서 위의 쿼리문을 실행해보면

 

이렇게 나온다. 스크립트 출력단에는 보이지않지만 NULL은 공백으로 처리된것이기때문에 NUM1과 NUM2가 정상적으로 출력된것을 확인할수 있다.

 

DECLARE를 선언해주면서 반드시 END;를 동시에 선언해주는것이 좋다. 우리는 JAVA에 익숙해져있기때문에 END; 선언보다는 {}가 익숙하다. 따라서 저 END;를 매번 까먹기 망정인데, 이런 오류가 쓸데없이 나면 스트레스부터 받기때문에

 

스트레스를 줄여주기 위해서는 선언과 동시에 END;까지 입력하고 그 사이에 BEGIN으로 선언부 작성을 해주는것이

 

마음의 평화를 유지하는 좋은 방법이 될거같다.

 

 

IF ELSIF문을 알아보자.

 

 

DECLARE

    num1 NUMBER := 100;
    num2 NUMBER := 300;
    
begin
    
    if(조건식) then
    
    elsif(조건식) then
    
    elsif(조건식) then
    
    else
   
end if;
    dbms_output.put_line('IF문 종료')
end;

 

IF~Then 그리고 ELSE IF가 아닌 ELSIF~then이 된다. 마지막으로 end if;로 if문 끝맺음을 해주어야 한다

 

DECLARE

    num1 NUMBER := 100;
    num2 NUMBER := 300;
    
begin
    
    if(num1 > num2) then
        dbms_output.put_line('넘1이 넘2보다 크다');
    elsif(num1 < num2) then
        dbms_output.put_line('아니야 넘2가 더 크다');
    elsif(num1 = num2) then
        dbms_output.put_line('같네.');
    else
        dbms_output.put_line('난 더 모르겠다.');
end if;
   
end;
/

 

 

이렇게 elsif, if문을 작성해보았다.

 

현재 변수에 num은 num2때문에 작기때문에 두번째줄 쿼리문이 실행되고 출력될것이다.

 

 

다음은 WHILE문을 알아보자

 

declare
    num3 NUMBER := 1;
    num4 number := 3;
begin
    while 조건부 
    loop
    반복실행문 실행부
    end loop;
end;
/

 

반복문이라 loop를 사용해준다

 

이걸 이용해서 2단짜리 구구단을 만들어보겠다.

 

declare
    num3 NUMBER := 1;
    num4 number := 2;
begin
    while num3 < 10 
    loop
    dbms_output.put_line(num4||'*'||num3||'='||num4*num3); --문자열 결합 ||을 이용
    num3 := num3+1; --num3을 1씩 증가, JAVA에서 num3++; 기능
    end loop;
end;
/

 

정상적으로 잘 출력된다.

 

마지막으로 For문을 이용하여 구구단을 만들어보겠다.

 

FOR문의 문법부터 살펴보자.

 

declare
    num3 NUMBER := 3;
begin
    for 증감변수명 in [reverse] 1..9 --증감 변수 선언 및 in 증감범위 선언
    loop
    dbms_output.put_line(num3||'*'||num4||'='||num3*num4); --문자열 결합 ||을 이용
    end loop;
end;
/

 

증감 변수명은 반복을 실행할때마다 1씩 무조건 증가한다, in 뒤에 오는 숫자는 몇부터 몇까지 증감을 반복할거냐고 정해주는, 즉 횟수 선언이 되겠다.

 

in뒤에 reverse를 붙일수도있는데 붙인다면 1부터 증가하는게 아닌 9부터 감소하는, 즉 감소식이 된다.

 

declare
    num3 NUMBER := 3;
begin
    for num4 in 1..9 --증감 변수 선언 및 in 증감범위 선언
    loop
    dbms_output.put_line(num3||'*'||num4||'='||num3*num4); --문자열 결합 ||을 이용
    end loop;
end;
/

declare
    num3 NUMBER := 3;
begin
    for num4 in REVERSE 1..9 --증감 변수 선언 및 in 증감범위 선언
    loop
    dbms_output.put_line(num3||'*'||num4||'='||num3*num4); --문자열 결합 ||을 이용
    end loop;
end;
/

 

reverse를 붙이면

 

역순이 된다.

 

추가로 반복문에 countinue를 중간에 넣어줄수 있는데 countinue when [조건식]을 붙여주면

 

해당 조건식에 만족한다면 다음 반복 수행을 하지않고 처음으로 돌아간다.

 

3단 구구단에서 3*5만 제거해보겠다.

 

declare
    num3 NUMBER := 3;
begin
    for num4 in 1..9 --증감 변수 선언 및 in 증감범위 선언
    loop
    CONTINUE when num4 = 5;
    dbms_output.put_line(num3||'*'||num4||'='||num3*num4); --문자열 결합 ||을 이용
    end loop;
end;
/

5는 제거되고 나머지 반복문이 실행되는것을 확인할수 있다.

 

마지막으로 내일 수업에 있을 더미테이블과 더미데이터 더미 시퀀스 만드는 쿼리문을 남겨두고 오늘 포스팅을 마친다.

 

--시퀀스생성 - noticeboard.nbno에 사용할 용도
CREATE SEQUENCE    notice_seq
START WITH 1
INCREMENT BY 1
NOCYCLE;

--테이블생성
CREATE TABLE noticeboard(
nbno number(4) constraint pk_notice_nbno primary key, --글번호
title varchar2(120) constraint nn_notice_title not null, --제목
contant varchar2(2000) constraint nn_notice_contant not null, --내용
cre_date date DEFAULT SYSDATE,                           --작성일
writer varchar2(30),                                                        --작성자
rcnt number(5) DEFAULT 0 constraint ck_notice_rcnt check(rcnt>=0),--조회수
 empno  NUMBER(30) constraint fk_notice_empno references  emp(empno)    --작성자id
);

--더미데이터
INSERT INTO noticeboard(nbno,title,contant,cre_date,writer,rcnt,empno)    
                   VALUES(notice_seq.nextval, '제목1','내용1',SYSDATE-10,'관리자',10,7900);
INSERT INTO noticeboard(nbno,title,contant,cre_date,writer,rcnt,empno)    
                   VALUES(notice_seq.nextval, '제목2','내용2',SYSDATE-10,'관리자',10,7900);
INSERT INTO noticeboard(nbno,title,contant,cre_date,writer,rcnt,empno)    
                   VALUES(notice_seq.nextval, '제목3','내용3',SYSDATE-10,'관리자',10,7900);
INSERT INTO noticeboard(nbno,title,contant,cre_date,writer,rcnt,empno)    
                   VALUES(notice_seq.nextval, '제목4','내용4',SYSDATE-10,'관리자',10,7900);
INSERT INTO noticeboard(nbno,title,contant,cre_date,writer,rcnt,empno)    
                   VALUES(notice_seq.nextval, '제목5','내용5',SYSDATE-10,'관리자',10,7900);
반응형