• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

오라클 DBMS 정리 09

08 Nov 2018

Reading time ~4 minutes

오라클 DBMS 정리 09 - PL/SQL 기본


PL/SQL

  • Procedural Language/SQL
  • DBMS에서 제공하는 언어적인 요소
    • PL/SQL 제공 안하는 DB도 존재
  • 구조
    • / : 정해진 코드를 수행
  • 에러 발생 시 쉽게 오류파악이 힘듦
    • DECLARE부터 1행 카운트, 오류 위치 출력
DECLARE
    변수선언
BEGIN
    코드작성
END;
/
  • 실행순서
  1. 코드작성
  2. 파일명.sql로 저장
  3. sqlplus에서 @파일명.sql로 실행
  • 출력설정
    • sqlplus에서 파일실행 전에 실행해줘야 출력설정이 됨
    • 매번 옵션이 초기화되기 때문에 보통 DECLARE 위에 명시
    • 출력설정을 안하면 PL/SQL은 실행되더라도 콘솔에 출력되지 않는다
-- 콘솔 출력설정
SET serveroutput ON

09-01

09-02

  • 출력함수 DBMS_OUTPUT
    • DBMS_OUTPUT.PUT_LINE - 실행 후 줄바꿈
    • DBMS_OUTPUT.PUT - 출력 후 줄바꾸지 않음
      • PUT다음에 linefeed가 있는 PUT_LINE이 와야 출력이 됨
-- 출력함수
-- 출력 후 줄을 변경해줌(/n)
DBMS_OUTPUT.PUT_LINE(출력할내용);

-- 출력 후 줄을 안바꿈
DBMS_OUTPUT.PUT(출력할내용);

-- 출력할 내용은 변수, '문자열', 연산식 등이 올 수 있음
-- '||'를 사용해서 변수나 문자열들을 붙여 출력 가능
-- 출력설정
SET serveroutput ON

DECLARE
-- 변수선언
    var VARCHAR2(15);

BEGIN
-- 코드작성
    SELECT '안녕 PL/SQL' INTO var
    FROM DUAL;

-- 출력함수
DBMS_OUTPUT.PUT_LINE(var);
DBMS_OUTPUT.PUT_LINE('hello PL/SQL');

END;
/

변수(Variable)

  • 프로그램에서 필요한 값을 메모리에 일시적으로 저장하기 위해 사용
  • 값에 대한 별명
    • 가독성 향상
  • 변수명은 유일해야 한다
    • 값할당은 여러번 가능 (이전에 할당된 값은 사라짐)
    • 쓰지않는 변수는 만들지 않는다..(상식)
DECLARE
   -- 변수 선언
   변수명 테이터형(크기);
   변수명 데이터형(크기) := 초기값;
BEGIN
   -- 값 할당
   변수명 := 값;

   -- 값 사용
   변수명 := 또다른변수명;
   DBMS_OUTPUT.PUT_LINE(변수명);
   DBMS_OUTPUT.PUT_LINE(3 + 변수명);
END;
  • 작성법
  1. 변수 선언 (DECLARE ~ BEGIN 사이)
  2. 값 할당 (BEGIN ~ END 사이)
  3. 값 사용
SET serveroutput ON

DECLARE
-- 1. 변수 선언 : 변수명 데이터형(크기);
    name1 VARCHAR2(60);
    name2 VARCHAR2(60);
    temp VARCHAR2(60);

BEGIN
-- 2. 값 할당 : 변수명 := 값;
    name1 := '오영영';
    name2 := '손솔솔';
    temp := name1;
    name1 := name2;
    name2 := temp;

-- 3. 사용 : 출력, 연산참여, 재할당
    DBMS_OUTPUT.PUT_LINE('name1 : '||name1);
    DBMS_OUTPUT.PUT_LINE('name2 : '||name2);
END;

변수 데이터형(Data Type)

09-03

  • 참조변수(Reference Variable)
    • 만들어진 테이블의 컬럼데이터형을 참조하여 변수를 만들 수 있음
    • 컬럼하나를 참조
      • 참조변수명 테이블명.컬럼명%TYPE
    • 테이블의 모든 컬럼참조 (record type, 레코드형 변수)
      • 레코드변수명 테이블명%ROWTYPE;
      • 사용은 레코드변수명.컬럼명 := 값;
    • 참조변수의 단점
      • 데이터형을 직관적으로 알 수 없다
      • 사용도중 데이터형이 변경될 수 있다
DECLARE
-- 컬럼 하나를 참조
    참조변수명 테이블명.컬럼명%TYPE := 값;

-- 테이블의 모든 컬럼 참조(RECORD TYPE)
    레코드변수명 테이블명%ROWTYPE;
BEGIN
    변수명 := 값;
    레코드타입변수명.컬럼명 := 값;
...
DECLARE
-- 테이블의 컬럼을 참조하여 변수를 만들 수 있다
    e_name emp.ename%TYPE;
BEGIN
    e_name := '이재현';
    DBMS_OUTPUT.PUT_LINE(e_name||'씨');
END;
/
DECLARE
-- 테이블의 모든 컬럼을 참조하여 변수 선언(RECORD TYPE, 레코드변수)    
    row_type cp_emp%ROWTYPE;
                             
BEGIN
-- cp_emp 테이블은 empno, ename, hiredate, sal 컬럼을 가짐  
-- RECORD TYPE 변수 사용 : 변수명.컬럼명
    row_type.empno := 1234;
    row_type.ename := 'young';
    row_type.hiredate := '1990-12-06';
    row_type.sal := 5000;
                        
    DBMS_OUTPUT.PUT_LINE(row_type.empno||'번, '
        ||row_type.ename||'은 생년월일이 '||row_type.hiredate||'고 '
        ||row_type.sal||'정도의 연봉을 받는다.');

END;
/          

입력값 받기

  • 프로그램을 동적으로 만들 때 사용
  • DECLARE 위에 정의
    • 입력값이 문자열인 경우 홑따옴표로 묶어 입력
      • 또는 할당할 때 문자열로 변환되도록 ‘&input변수’ 로 처리
    • ACCEPT구문 마지막에 ‘;’ 찍지 않음
      • 블럭 내부안에서만 ‘;’를 찍는다!
ACCEPT 입력될변수명 PROMPT '콘솔창에 출력될 메시지'

DECLARE
...
BEGIN
    ... := &입력될변수명 
    ...
END;
/

09-04

  • 기존의 코드가 입력된 값으로 변경되는 검증옵션 수행

  • 검증옵션 끄기

SET verify OFF
SET serveroutput ON  
-- 검증옵션 끄기 
SET verify OFF

ACCEPT input_name PROMPT '이름을 입력하세요 : '
ACCEPT input_age  PROMPT '나이를 입력하세요 : '

DECLARE
    name VARCHAR2(15);
    age NUMBER(3);
BEGIN             

-- 입력값이 문자열인 경우 ''로 묶어서 문자열로 변환
    name := '&input_name';
    age := &input_age;

    DBMS_OUTPUT.PUT_LINE('이름 : '||name||'님 나이는 '||age||'살입니다.');
END;
/

09-05

  • &는 주석안에 있어도 인식이 된다
    • PL/SQL에서는 주석안이라도 &는 쓰면 안됨
BEGIN                    
-- 주석안에 &가 있으면??  &comment
END;
/

09-06

-- 태어난해 출력 : XX살 태어난해 XXXX년생

ACCEPT input_age PROMPT '나이를 입력하세요 : '

DECLARE
    age NUMBER(3);
    yob NUMBER(4);
BEGIN              
    age := &input_age;
    yob := TO_CHAR(SYSDATE, 'yyyy')-age+1;

    DBMS_OUTPUT.PUT_LINE(age||'살 태어난해 : '||yob||'년생');

-- 문자열은 연산이 안된다! -> DBMS가 자동 형변환
-- 아래 PUT_LINE함수는 에러발생
-- '||'는 산술연산자(+,-)보다 우선순위가 높아서 하이라이트한 부분먼저 붙고 산술연산이 시도됨
    DBMS_OUTPUT.PUT_LINE(age||'살 태어난해 : '||TO_CHAR(SYSDATE, 'yyyy')-age+1||'년생');

-- || 사이에 있는 값을 연산 시킬려면 ||보다 먼저 수행되도록 ()를 붙인다
-- 산술연산자(*,/)는 안붙여도 된다(우선순위가 높기 때문에)
    DBMS_OUTPUT.PUT_LINE(age||'살 태어난해 : '||
         (TO_CHAR(SYSDATE, 'yyyy')-age+1)||'년생');

END;
/

제어문

  • 프로그램의 순차적인 흐름을 바꿔줄 수 있는 문장
    • BEGIN ~ END 사이에서 사용
  • 조건문, 반복문, 분기문 3가지 제공
  • 조건문
    • IF
  • 반복문
    • LOOP
    • FOR
    • WHILE
  • 분기문
    • EXIT
    • RETURN

조건문 IF

  • 조건을 부여하여 조건에 맞는 경우 코드를 수행할 때 사용
  • 단일 IF, IF ~ ELSE, 다중 IF(ELSIF) 3가지 형태로 사용

  • 단일 IF
    • 조건에 맞는 경우, 코드를 실행할 때 사용
...
BEGIN

    IF 조건식 THEN
        조건에 맞을 때 수행할 문장들;
    END IF;

END;
/
  • IF~ELSE
    • 둘 중 하나의 코드를 실행해야 하는 경우
BEGIN
    IF 조건식 THEN
        조건에 맞을 때 수행할 문장;
    ELSE 
        조건에 맞지 않을 때 수행할 문장;
    END IF;
END;
  • 다중 IF (ELSIF)
    • 연관성 있는 여러 조건을 비교할 때 사용
BEGIN

    IF 조건1 THEN
        조건1에 맞을 때 수행할 문장;
    ELSIF 조건2 THEN
        조건2에 맞을 때 수행할 문장;
    ELSIF 조건3 THEN
        조건3에 맞을 때 수행할 문장;
    ELSIF ...
        ...
    ELSE
        모든 조건에 맞지 않았을 때 수행할 문장
    END IF;

END;

숙제풀이1

숙제풀이2

숙제풀이3

숙제풀이4



오라클DBMS