본문 바로가기

Oracle

[211004] PL/SQL

 PL/SQL


Procedural Language extension to SQL의 약자로 오라클 자체에 내장되어 있는 절차적 언어
SQL의 단점을 보완하여 SQL문장 내에서 변수의 정의, 조건 처리, 반복 처리 등 지원

 


예시

SET SERVEROUTPUT ON;
* 프로시저를 사용하여 출력하는 내용을 화면에 보여주도록 설정하는 환경변수로
기본 값은 OFF여서 ON으로 변경

BEGIN

         DBMS_OUTPUT.PUT_LINE(‘HELLO WORLD’);

END;
/        --  ; 찍고 / 포함해서 작성

* PUT_LINE이라는 프로시저를 이용하여 출력 (DBMS_OTUPUT 패키지에 속해있음)


PL/SQL 실습

 

-- SET SERVEROUTPUT ON;
-- SET AUTOCOMMIT OFF;

BEGIN
    DBMS_OUTPUT.PUT_LINE('Hello PL/SQL');
END;
/

DECLARE
    /* 
      변수 선언부로 BEGIN 안에 사용할 변수를 미리 구성한다.

      변수명 데이터타입;
    */
    var1 NUMBER;  -- 테이블 만들 때 썼던 데이터 타입들
    var2 VARCHAR2(10);
    var3 CHAR(1) := 'F';  -- 생성과 동시에 초기화 (BEGIN에서 할당할 필요 X)
BEGIN
    var1 := 10;  -- 반드시 := (이미 = 은 비교 연산으로 사용되므로 콜론으로 할당 구별)
    var2 := 'abcd';

    DBMS_OUTPUT.PUT_LINE('var1 출력 : ' || (var1 + 10));   -- 출력, 괄호로 연산 우선
    DBMS_OUTPUT.PUT_LINE('var1 출력 : ' || var2);
    DBMS_OUTPUT.PUT_LINE('var3 출력 : ' || var3);
END;
/

 

응용 1

 

<SELECT 해서 나온 행을 INTO로 저장>  - 단, 조회 결과는 반드시 1개의 행이어야 한다.

이해를 위해 블록으로 SELECT 결과만 구해본 것

 


DECLARE
    -- 그냥 변수 담을 공간을 만든 것 뿐 

    EMP_ID NUMBER;
    EMP_NAME VARCHAR2(50);
BEGIN
    SELECT EMPLOYEE_ID         -- INTO 와 대응 (순서 바뀌면 에러)
         , FIRST_NAME || ' ' || LAST_NAME NAME   -- 사실 연산자 사용 권장하지 않음
      INTO EMP_IDEMP_NAME    -- 위에 만들어진 변수 공간에 조회한 데이터를 저장 (SELECT 와 대응)
      FROM EMPLOYEES
     WHERE EMPLOYEE_ID = 100;

     DBMS_OUTPUT.PUT_LINE('사번 : ' || EMP_ID);
     DBMS_OUTPUT.PUT_LINE('이름 : ' || EMP_NAME); 
END;
/

-- 조회한 컬럼과 저장 하고자 하는 변수 담을 공간은 타입이 맞아야 함
-- 데이터 크기도 적절해야 하므로 가급적 조회 SELECT 절에는 연산자(|| ' ' ||) 쓰지 않는 것 권장 (응용 2 발전된 형태의 구문) 

 

 

응용 2

 

<레퍼런스 타입 활용>

-- 타입을 직접 명시하지 않고 이미 정의된 타입 참조

DECLARE
    EMP_FNAME EMPLOYEES.FIRST_NAME%TYPE;   -- 레퍼런스 타입 (테이블 컬럼 타입이 바뀌더라도 구문 문제가 없게 됨)
    EMP_LNAME EMPLOYEES.LAST_NAME%TYPE;
    EMP_ID NUMBER
BEGIN
    SELECT FIRST_NAME
         , LAST_NAME
         , EMPLOYEE_ID
      INTO EMP_FNAME
         , EMP_LNAME
         , EMP_ID
      FROM EMPLOYEES
     WHERE EMPLOYEE_ID = 106;

    DBMS_OUTPUT.PUT_LINE('사번 : ' || EMP_ID);
    DBMS_OUTPUT.PUT_LINE('이름 : ' || EMP_FNAME || ' ' || EMP_LNAME); 
END;
/

 

응용3

 

<변수 하나에 전체 행 데이터 삽입>


-- 하나의 변수에 전체 행 데이터가 들어가는 것

DECLARE
    row_data EMPLOYEES%ROWTYPE;  -- 전체 행의 타입
BEGIN
    SELECT *  -- 행의 전체 열 조회해야 함
      INTO row_data
      FROM EMPLOYEES
     WHERE EMPLOYEE_ID = 100;

    DBMS_OUTPUT.PUT_LINE('사번 : ' || row_data.EMPLOYEE_ID);    -- 점 찍고 사용하면 된다.
    DBMS_OUTPUT.PUT_LINE('이름 : ' || row_data.FIRST_NAME || ' ' || row_data.LAST_NAME); 
END;
/

 

응용 4

 

<선택문>  IF ~ THEN ~ ELSIF ~ ELSE ~ END IF

-- 단순 갯수 출력

DECLARE

    cnt NUMBER;
BEGIN
    SELECT COUNT(*)
      INTO cnt
      FROM EMPLOYEES
     WHERE DEPARTMENT_ID = 80;

    DBMS_OUTPUT.PUT_LINE('부서인원 : ' || cnt);
END;
/
-- 선택문 사용

DECLARE

    cnt NUMBER;
BEGIN
    SELECT COUNT(*)
      INTO cnt
      FROM EMPLOYEES
     WHERE DEPARTMENT_ID = 100;             -- 100, 90, 80 넣어서 확인

    DBMS_OUTPUT.PUT_LINE('부서인원 : ' || cnt);
    IF(cnt >= 30THEN
        DBMS_OUTPUT.PUT_LINE('부서인원이 30명 이상 입니다.');
    ELSIF(cnt >= 5THEN                            -- ELSE IF : ELSIF 로 쓴다.
        DBMS_OUTPUT.PUT_LINE('부서인원이 5명 이상 입니다.');
    ELSE
        DBMS_OUTPUT.PUT_LINE('부서인원이 30명 미만 입니다.');
    END IF;  -- IF문 종료
END;
/

 

'Oracle' 카테고리의 다른 글

[211007~8] FUNCTION, 복합 연습문제  (0) 2021.10.08
[211005] 반복문(LOOP)  (0) 2021.10.07
[211004] INDEX (TABLE SCAN / INDEX SCAN)  (0) 2021.10.04
[211004] SEQUENCE, 트랜젝션, SYNONYM  (0) 2021.10.04
[091001] VIEW  (0) 2021.10.01