PL/SQL(Procedual LANGUAGE SQL)
- 기본 SQL이 구조적 언어이기 때문에 변수,반복,분기 등의 기능이 제거되어 제공
- 기본 SQL에 절차적 언어의 특징을 추가한 SQL을 PLSQL이라 함
- 미리 작성되어 컴파일한 형태로 서버에 저장됨 - 실행 속도의 향상과 네트웍 트래픽 감소
- 블록 구조로 복수개의 SQL문을 헌번에 실행할 수 있음
- 모듈화, 캡슐화 기능 제공
- 익명블록(Anonymous Block), Stored Procedure, User Defined Function, Trigger, Package 등이 제공됨
1. 익명블록(Anonymous Block)
- PL/SQL의 기본 구조 제공
- 이름이 없어 실행파일로 저장되지 않음
(기본 구조)
DECLARE
선언영역 : 변수,상수,커서 선언
BEGIN
실행영역 : 처리할 명령문들을 절차적으로 기술
[EXCEPTION
예외처리 영역
]
END;
사용예) 키보드로 부서번호를 하나 입력 받아 해당부서에 가장 먼저 입사한 사원정보를 출력하시는 블록을 작성하시오.
출력은 사원번호,사원명,입사일,직무명이다.
ACCEPT P_DID PROMPT '부서번호 입력(10~110) : '
DECLARE
L_EID HR.EMPLOYEES.EMPLOYEE_ID%TYPE;
L_NAME VARCHAR2(80);
L_HDATE DATE;
L_JTITLE HR.JOBS.JOB_TITLE%TYPE;
L_DID HR.DEPARTMENTS.DEPARTMENT_ID%TYPE:=TO_NUMBER('&P_DID');
BEGIN
SELECT TA.AEID, TA.ENAME, TA.HDATE, TA.BJT
INTO L_EID,L_NAME,L_HDATE,L_JTITLE
FROM (SELECT A.EMPLOYEE_ID AS AEID,A.EMP_NAME AS ENAME,A.HIRE_DATE AS HDATE,B.JOB_TITLE AS BJT
FROM HR.EMPLOYEES A, HR.JOBS B
WHERE A.DEPARTMENT_ID=L_DID
AND A.JOB_ID=B.JOB_ID
ORDER BY 3) TA
WHERE ROWNUM=1;
DBMS_OUTPUT.PUT_LINE('부서번호 : '||L_DID);
DBMS_OUTPUT.PUT_LINE('사원서번호 : '||L_EID);
DBMS_OUTPUT.PUT_LINE('사원명 : '||L_NAME);
DBMS_OUTPUT.PUT_LINE('입사일 : '||L_HDATE);
DBMS_OUTPUT.PUT_LINE('직무명 : '||L_JTITLE);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('에러발생 :'||SQLERRM);
END;
2. 변수
- 개발 언어의 변수와 같은 기능
- 종류 : SCLAER, REFERENCE, COMPOSITE:배열, BIND:매개변수 변수
- 사용하는 데이터 타입 : SQL에서 사용하는 데이터 타입,
PLS_INTEGER, BINARY_INTEGER >> 4BYTE 정수(2147483637~-2147483638)
BOOLEAN(true,false,null)
선언형식)
변수명 [CONSTANT] 데이터타입|참조타입 [:=초기값]
- 'CONSTANT' : 상수 선언시 사용
- 참조타입 :
- 테이블명.컬럼명%TYPE:선언할 변수의 자료형과 크기가 '테이블의 칼럼'과 동일하게 설정
- 테이블명%ROWTYPE : 해당 테이블의 한 행과 동일한 타입(레코드 형)
- ' :=초기값' : 초기값이 필요한 경우(NUMBER타입은 필수로 초기화 해야함) 기술
사용예) 10~110번 사이의 임의의 부서코드를 생성하여 해당부서의 부서명과 인원수를 조회하여 출력하는 익명블록 작성
DECLARE
L_DNAME DEPT.DEPARTMENT_NAME%TYPE;
L_CNT NUMBER:=0;
L_DID HR.EMPLOYEES.DEPARTMENT_ID%TYPE;
BEGIN
L_DID:=TRUNC(DBMS_RANDOM.VALUE(10,119),-1); -- 110으로 할 경우 110이 나올 확률 희박
SELECT A.DEPARTMENT_NAME AS DNAME,
COUNT(*) AS CNT
INTO L_DNAME,L_CNT
FROM HR.DEPARTMENTS A, HR.EMPLOYEES B
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID
AND A.DEPARTMENT_ID=L_DID
GROUP BY A.DEPARTMENT_NAME;
DBMS_OUTPUT.PUT('부서코드 : '||L_DID);
DBMS_OUTPUT.PUT(', 부서명 : '||L_DNAME);
DBMS_OUTPUT.PUT(', 인원수 : '||L_CNT);
DBMS_OUTPUT.PUT_LINE(' ');
END;
사용예) 10~110번 사이의 임의의 부서코드를 생성하여 해당부서에 소속된 사원의
사원번호,사원명,입사일,급여를 조회하여 출력하는 익명블록 작성
DECLARE
L_EID HR.EMPLOYEES.EMPLOYEE_ID%TYPE; --사원번호
L_ENAME VARCHAR2(80); --사원명
L_HDATE DATE; --입사일
L_SALARY NUMBER:=0; --급여
L_DNAME VARCHAR2(100); --부서명
L_DID HR.DEPARTMENTS.DEPARTMENT_ID%TYPE;
CURSOR CUR_EMP01(P_DID HR.DEPARTMENTS.DEPARTMENT_ID%TYPE) IS
SELECT EMPLOYEE_ID,EMP_NAME,HIRE_DATE,SALARY
FROM HR.EMPLOYEES
WHERE DEPARTMENT_ID=P_DID;
BEGIN
L_DID:=TRUNC(DBMS_RANDOM.VALUE(10,119),-1);
SELECT DEPARTMENT_NAME INTO L_DNAME
FROM HR.DEPARTMENTS
WHERE DEPARTMENT_ID=L_DID;
DBMS_OUTPUT.PUT_LINE('부서번호 : '||L_DID||'('||L_DNAME||')');
OPEN CUR_EMP01(L_DID);
LOOP
FETCH CUR_EMP01 INTO L_EID,L_ENAME,L_HDATE,L_SALARY;
EXIT WHEN CUR_EMP01%NOTFOUND; -- 커서에 포함된 자료가 존재하지 않을 때,
DBMS_OUTPUT.PUT_LINE(L_EID||' '||RPAD(L_ENAME,25)||L_HDATE||' '||
TO_CHAR(L_SALARY,'999,999'));
DBMS_OUTPUT.PUT_LINE('------------------------------------------------');
END LOOP;
DBMS_OUTPUT.PUT_LINE('전체 직원 수 : '||CUR_EMP01%ROWCOUNT);
CLOSE CUR_EMP01;
END;
'DBMS' 카테고리의 다른 글
[DBMS/Oracle] 저장 프로시져(STORED PROCEDURE) (0) | 2023.03.18 |
---|---|
[DBMS/Oracle] IF문, 커서(CURSOR), 반복명령 (0) | 2023.03.18 |
[DBMS/Oracle] 인덱스(INDEX) (0) | 2023.03.17 |
[DBMS/Oracle] 동의어(SYNONYM) (0) | 2023.03.17 |
[DBMS/Oracle] 시퀀스(SEQUENCE) (0) | 2023.03.17 |