[DECLARE]
[변수 선언]
BEGIN
수행할 PL/SQL
END;
SET SERVEROUTPUT OFF
SET SERVEROUTPUT ON;
HR 계정의 EMPLOYEES 테이블을 SCOTT 계정으로 복사해오기
CREATE TABLE EMPLOYEES
AS (SELECT *
FROM HR.EMPLOYEES);
기본키 다시 생성
ALTER TABLE EMPLOYEES
ADD CONSTRAINT PK_EMPLOYEES PRIMARY KEY(EMPLOYEE_ID);
서버메시지 출력 가능 상태로 변경
- 한 번만 실행하면 된다.
SET SERVEROUTPUT ON;
서버메시지 출력
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello'); -- Hello 출력 후 줄 바꿈
END;
:=
콜론등호 DECLARE
에서 처리DECLARE
-- 스칼라 변수 선언
NAME VARCHAR2(20 BYTE);
AGE NUMBER(3);
BEGIN
NAME := '손석구';
AGE := 40;
DBMS_OUTPUT.PUT_LINE('내 이름은 ' || NAME || '입니다.');
DBMS_OUTPUT.PUT_LINE('내 나이는 ' || AGE || '살입니다.');
END;
테이블명.칼럼%TYPE
DECLARE
-- 참조 변수 선언
NAME EMPLOYEES.FIRST_NAME%TYPE;
BEGIN
NAME := '손석구';
DBMS_OUTPUT.PUT_LINE('내 이름은 ' || NAME || '입니다.');
END;
SELECT 칼럼 INTO 변수 FROM 테이블 WHERE 조건식
문제, EMPLOYEE_ID가 100인 회원의 FIRST_NAME, LAST_NAME, SALARY 정보를 참조 변수에 저장
DECLARE
F_NAME EMPLOYEES.FIRST_NAME%TYPE;
L_NAME EMPLOYEES.LAST_NAME%TYPE;
V_SALARY EMPLOYEES.SALARY%TYPE;
BEGIN
SELECT
FIRST_NAME, LAST_NAME, SALARY
INTO
F_NAME, L_NAME, V_SALARY
FROM
EMPLOYEES
WHERE
EMPLOYEE_ID = 100;
DBMS_OUTPUT.PUT_LINE(F_NAME || L_NAME || V_SALARY);
END;
행(Row)
DECLARE
-- 레코드 변수 타입 정의 (타입 만들기)
TYPE MY_TYPE IS RECORD(
V_FNAME EMPLOYEES.FIRST_NAME%TYPE,
V_LNAME EMPLOYEES.LAST_NAME%TYPE,
V_SALARY EMPLOYEES.SALARY%TYPE
);
-- 레코드 변수 선언 (변수 만들기)
V_ROW MY_TYPE;
BEGIN
SELECT
FIRST_NAME, LAST_NAME, SALARY
INTO
V_ROW
FROM
EMPLOYEES
WHERE
EMPLOYEE_ID = 100;
DBMS_OUTPUT.PUT_LINE(V_ROW.V_FNAME || V_ROW.V_LNAME || V_ROW.V_SALARY);
END;
테이블%ROWTYPE
DECLARE
-- 행 변수 선언
V_ROW EMPLOYEES%ROWTYPE;
BEGIN
SELECT *
INTO V_ROW
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
DBMS_OUTPUT.PUT_LINE(V_ROW.FIRST_NAME || V_ROW.LAST_NAME || V_ROW.SALARY);
END;
IF 조건식 THEN
실행문
ELSIF 조건식 THEN
실행문
ELSE
실행문
END IF;
성인 / 미성년자
DECLARE
AGE NUMBER(3);
RESULT VARCHAR2(20 BYTE);
BEGIN
AGE := 45;
IF AGE >= 20 THEN
RESULT := '성인';
ELSE
RESULT := '미성년자';
END IF;
DBMS_OUTPUT.PUT_LINE(AGE || '살은 ' || RESULT || '입니다.');
END;
학점 (A,B,C,D,F)
DECLARE
GRADE VARCHAR2(3);
RESULT VARCHAR2(20 BYTE);
BEGIN
GRADE := 100;
IF GRADE >= 90 THEN
RESULT := 'A';
ELSIF GRADE >= 80 THEN
RESULT := 'B';
ELSIF GRADE >= 70 THEN
RESULT := 'C';
ELSIF GRADE >= 60 THEN
RESULT := 'D';
ELSE
RESULT := 'F';
END IF;
DBMS_OUTPUT.PUT_LINE(GRADE || '점은 ' || RESULT || '입니다.');
END;
EMPLOYEE_ID가 150인 사원의 연봉을 참조하여
- 15000 이상이면 '고연봉', 10000 이상이면 '중연봉', 나머지는 '저연봉'
DECLARE
SAL EMPLOYEES.SALARY%TYPE;
RES VARCHAR2(20 BYTE);
BEGIN
SELECT SALARY
INTO SAL
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 150;
IF SAL >= 15000 THEN
RES := '고연봉';
ELSIF SAL >= 10000 THEN
RES := '중연봉';
ELSE
RES := '저연봉';
END IF;
DBMS_OUTPUT.PUT_LINE('연봉 ' || SAL || '은 ' || RES || '입니다.');
END;
CASE
WHEN 조건식 THEN
실행문
WHEN 조건식 THEN
실행문
ELSE
실행문
END CASE;
주민번호를 이용해 성별 조회하기
DECLARE
SNO VARCHAR2(14 BYTE);
GENDER_NUM VARCHAR2(1 BYTE);
GENDER VARCHAR2(1 BYTE);
BEGIN
SNO := '901010-1234567';
SELECT SUBSTR(SNO, 8, 1)
INTO GENDER_NUM
FROM DUAL;
CASE
WHEN GENDER_NUM = '1' THEN
GENDER := 'M';
WHEN GENDER_NUM = '2' THEN
GENDER := 'F';
END CASE;
DBMS_OUTPUT.PUT_LINE('성별은 ' || GENDER || '입니다.');
END;
WHILE 조건식 LOOP
실행문
END LOOP;
1 ~ 5 출력하기
DECLARE
N NUMBER(1);
BEGIN
N := 1;
WHILE N <= 5 LOOP
DBMS_OUTPUT.PUT_LINE(N);
N := N + 1;
END LOOP;
END;
EMPLOYEES 테이블의 모든 사원의 FIRST_NAME, LAST_NAME 조회하기
- FIRST_NAME과 LAST_NAME을 레코드 변수에 저장하고 해당 값을 조회
- 레코드 변수는 사원 한 명의 정보만 저장할 수 있으므로 한 명씩 저장 후 출력
- 사원번호는 100 ~ 206 값을 가진다.
DECLARE
-- 참조 변수 선언
EMP_NO EMPLOYEES.EMPLOYEE_ID%TYPE;
-- 레코드 변수 정의
TYPE NAME_TYPE IS RECORD(
FNAME EMPLOYEES.FIRST_NAME%TYPE,
LNAME EMPLOYEES.LAST_NAME%TYPE
);
-- 레코드 변수 선언
FULL_NAME NAME_TYPE;
BEGIN
-- 사원번호(100 ~ 206) 기준으로 WHILE LOOP
EMP_NO := 100;
WHILE EMP_NO <= 206 LOOP
SELECT FIRST_NAME, LAST_NAME
INTO FULL_NAME
FROM EMPLOYEES
WHERE EMPLOYEE_ID = EMP_NO;
DBMS_OUTPUT.PUT_LINE(FULL_NAME.FNAME || ' ' || FULL_NAME.LNAME);
EMP_NO := EMP_NO + 1;
END LOOP;
END;
FOR 변수 IN 시작..종료 LOOP
실행문
END LOOP;
1 ~ 5
DECLARE
FOR N IN 1..5 LOOP
DBMS_OUTPUT.PUT_LINE(N);
END LOOP;
END;
짝수 / 홀수
DECLARE
N NUMBER;
MODULAR NUMBER(1); -- 2로 나눈 나머지 값을 저장
RESULT VARCHAR2(10 BYTE);
BEGIN
FOR N IN 1..10 LOOP
SELECT MOD(N, 2)
INTO MODULAR
FROM DUAL;
IF MODULAR = 0 THEN
RESULT := '짝수';
ELSE
RESULT := '홀수';
END IF;
DBMS_OUTPUT.PUT_LINE(N || '은 ' || RESULT || '입니다.');
END LOOP;
END;
EMPLOYEES 테이블의 모든 사원의 연봉합계 / 연봉평균 조회하기
DECLARE
EMP_NO EMPLOYEES.EMPLOYEE_ID%TYPE;
SAL EMPLOYEES.SALARY%TYPE;
TOTAL NUMBER;
CNT NUMBER;
AVERAGE NUMBER;
BEGIN
TOTAL := 0;
CNT := 0;
FOR EMP_NO IN 100..206 LOOP
SELECT SALARY
INTO SAL
FROM EMPLOYEES
WHERE EMPLOYEE_ID = EMP_NO;
TOTAL := TOTAL + SAL;
CNT := CNT + 1;
END LOOP;
AVERAGE := TOTAL / CNT;
DBMS_OUTPUT.PUT_LINE('연봉합계 : ' || TOTAL);
DBMS_OUTPUT.PUT_LINE('연봉평균 : ' || AVERAGE);
END;
DEPARTMENT_ID가 50인 사원정보를 DEPT50 테이블에 복사하기
- EMPLOYEES와 구조가 동일한 DEPT50 테이블 생성
- 행 변수를 이용해 EMPLOYEES 정보 읽기
- 행 변수의 DEPARTMENT_ID가 50이면 DEPT50에 INSERT
CREATE TABLE DEPT50
AS (SELECT * FROM EMPLOYEES WHERE 1 = 2);
DECLARE
V_ROW EMPLOYEES%ROWTYPE;
BEGIN
FOR V_ROW IN(SELECT * FROM EMPLOYEES) LOOP
IF V_ROW.DEPARTMENT_ID = 50 THEN
INSERT INTO DEPT50 VALUES V_ROW;
END IF;
END LOOP;
COMMIT;
LOOP 종료
DECLARE
N NUMBER;
BEGIN
N := 1;
WHILE TRUE LOOP
IF N > 100 THEN
EXIT;
END IF;
N := N + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(N);
END;
DEPARTMENT_ID가 50인 사원을 제외하고 연봉합계 조회하기
DECLARE
EMP_ID EMPLOYEES.EMPLOYEE_ID%TYPE;
SAL EMPLOYEES.SALARY%TYPE;
DEPT_ID EMPLOYEES.DEPARTMENT_ID%TYPE;
TOTAL NUMBER;
BEGIN
TOTAL := 0;
FOR EMP_ID IN 100..206 LOOP
SELECT SALARY, DEPARTMENT_ID
INTO SAL, DEPT_ID
FROM EMPLOYEES
WHERE EMPLOYEE_ID = EMP_ID;
IF DEPT_ID = 50 THEN
CONTINUE;
END IF;
TOTAL := TOTAL + SAL;
END LOOP;
DBMS_OUTPUT.PUT_LINE('연봉합계 : ' || TOTAL);
END;
DECLARE
-- SALARY 칼럼의 모든 값을 저장할 배열 생성
-- 배열의 타입 정의
TYPE SALARY_TYPE IS TABLE OF EMPLOYEES.SALARY%TYPE INDEX BY BINARY_INTEGER;
-- 배열의 선언
SALARIES SALARY_TYPE;
-- 인덱스 선언
I BINARY_INTEGER;
-- 행(Row) 변수 선언
V_ROW EMPLOYEES%ROWTYPE;
BEGIN
I := 0;
FOR V_ROW IN(SELECT * FROM EMPLOYEES) LOOP
SALARIES(I) := V_ROW.SALARY;
I := I + 1;
END LOOP;
FOR I IN 0..106 LOOP
DBMS_OUTPUT.PUT_LINE(SALARIES(I));
END LOOP;
END;
EXCEPTION
WHEN 예외 THEN
예외처리
WHEN 예외 THEN
예외처리
WHEN OTHERS THEN
예외처리
DECLARE
FNAME EMPLOYEES.FIRST_NAME%TYPE;
BEGIN
SELECT FIRST_NAME
INTO FNAME
FROM EMPLOYEES
--WHERE EMPLOYEE_ID = 0; -- 존재하지 않는 사원 조회
WHERE DEPARTMENT_ID = 50; -- 변수에 저장할 데이터가 너무 많다.
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('조회된 데이터가 없음');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('예외코드 ' || SQLCODE);
DBMS_OUTPUT.PUT_LINE('예외메시지 ' || SQLERRM);
END;