몰입하며 나아가는 개발이란

Language/SQL

Oracle PL/SQL PL02 (Procedural extension to Structured Query Language)

류하을 2019. 12. 20. 18:49

Cursor

저장 주소 공간 으로 볼 수 있으며, C언어에서 pointer 와 같은역할을 한다. 

암시적Cursor 와 명시적Cursor가 있다.

 

암시적 커서 : 자동생성
        SQL%ROWCOUNT : ROW의 수
        SQL%FOUND : ROW의 수가 한개이상일 경우
        SQL%NOTFOUND : ROW의 수가 0
    
명시적 커서 : 수동생성

암시적CURSOR

SET SERVEROUTPUT ON

CREATE OR REPLACE PROCEDURE implicit_cursor(p_empname IN employees.first_name%TYPE)
IS
v_sal employees.salary%TYPE;
v_update_row NUMBER;    -- 몇개의 행이 수정되는지 조사하는 부분의 변수

BEGIN
    -- 검색
SELECT salary INTO v_sal
FROM employees
WHERE first_name = p_empname;
    
-- (검색된 데이터가 있는 경우 조건)
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('검색된 데이터가 있습니다');
END IF;
    
-- 수정
UPDATE employees
SET salary = salary * 1.1
WHERE first_name = p_empname;
    
-- 출력
v_update_row := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('급여가 인상된 사원수:' || v_update_row);

-- 예외출력
EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('검색된 데이터가 없습니다');

END;
/

EXECUTE implicit_cursor('Neena');
ROLLBACK;

명시적CURSOR

CREATE OR REPLACE PROCEDURE expCursor_test(v_deptno IN departments.department_id%TYPE)
IS
CURSOR dept_avg
IS

SELECT d.department_name, COUNT(e.employee_id) CNT,
ROUND(AVG(salary), 3) SAL
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND e.department_id = v_deptno
GROUP BY d.department_name;
    
-- CURSOR에 PATCH하기 위한 변수들을 선언
v_dname departments.department_name%TYPE;
emp_cnt NUMBER;
sal_avg NUMBER;   
    
BEGIN

-- CURSOR OPEN    
OPEN dept_avg;
    
-- CURSOR FETCH
FETCH dept_avg INTO v_dname, emp_cnt, sal_avg;

DBMS_OUTPUT.PUT_LINE('부서명:' || v_dname);
DBMS_OUTPUT.PUT_LINE('사원수:' || emp_cnt);
DBMS_OUTPUT.PUT_LINE('급여평균:' || sal_avg);

-- CURSOR CLOSE
CLOSE dept_avg;

END;
/
EXEC expcursor_test(50);