PL/SQL 커서(Cursor)와 예외처리

2025. 6. 11. 00:04·database

PL/SQL에서 SELECT를 할 때 주의해야 할 점이 있다.

바로 반드시 하나의 행만을 검색해야 한다는 것이다!

이게 뭔 소리냐면, select를 통해 값을 조회하고 그 값을 변수에 넣는 작업을 할 때 여러개의 행을 조회해 버리면 오류가 발생하기 때문에 하나의 행만을 조회하도록 해야 한다!

만약 두 개 이상의 데이터 행을 추출하면 TOO_MANY_ROWS 오류가 발생하고, 어떤 데이터도 추출하지 못하면NO_DATA_FOUND 오류가 발생한다.

 

아니 그러면 여러 행을 한번에 조회해서 사용할 수는 없는 것인가??

이럴 때 바로 커서(Cursor)를 사용하면 된다!

 

커서: SQL 처리 결과가 저장된 작업 영역에 이름을 지정하고 저장된 정보를 접근할 수 있게 함. SQL 명령을 실행시키면 서버는 명령을 파싱하고 실행하기 위한 메모리 영역을 오픈하는데 이 영역을 cursor라고 부른다

종류: 암시적 커서, 명시적 커서

 

암시적 커서

  • 오라클 데이터베이스에서 실행되는 모든 SQL문장은 암시적인 커서
  • SQL 문이 실행되는 순간 자동으로 열림과 닫힘 실행
SQL%ROWCOUNT 해당 SQL 문에 영향을 받는 행의 수
SQL%FOUND 해당 SQL문의 영향을 받는 행의 수가 1개 이상일 경우TRUE
SQL%NOTFOUND 해당 SQL 문에 영향을 받는행의 수가 없을 경우TRUE
SQL%ISOPEN 암시적 커서가 열려 있는지의 여부검색 항상FALSE(실행한 후 바로커서를 닫기 때문)

 

명시적 커서

  • DECLARE : 이름이 있는 SQL 영역 생성
  • OPEN : 커서 활성화
  • FETCH : 커서의 현재 데이터행을 해당 변수에 넘김
  • EMPTY : 현재 데이터행의 존재 여부 검사, 레코드가 없으면 FETCH 하지 않음
  • CLOSE : 커서가 사용한 자원 해제
DECLARE
 v_empno emp.empno%TYPE;
 v_ename emp.ename%TYPE;
 CURSOR emp_list IS --커서 선언
 	SELECT empno, ename
 	FROM emp;
BEGIN
 OPEN emp_list; --커서 연결
 LOOP
 	FETCH emp_list INTO v_empno, v_ename; --커서로부터 데이터 패치
 	EXIT WHEN emp_list%NOTFOUND; 
    --%NOTFOUND fetch한 데이터가 행을 리턴하지 않으면 True
	DBMS_OUTPUT.PUT_LINE(v_ename);
 END LOOP;
 DBMS_OUTPUT.PUT_LINE('전체데이터수' || TO_CHAR(emp_list%ROWCOUNT));
 --%ROWCOUNT 현재까지 반환된 모든 데이터 행 수
 CLOSE emp_list; --커서 닫기
END;

 

FOR 문을 사용하면 커서의 OPEN, FETCH, CLOSE가 자동으로 발생 됨!

레코드 이름도 자동 선언되므로 따로 선언할 필요도 없음!

DECLARE
 	CURSOR dept_cnt IS
 		SELECT b.dname, COUNT(a.empno) cnt
 		FROM    emp a, dept b
 		WHERE  a.deptno = b.deptno
 		GROUP  BY b.dname;
BEGIN
 	FOR emp_list IN dept_cnt LOOP
 		DBMS_OUTPUT.PUT_LINE('부서명 : ' || emp_list.dname);
 		DBMS_OUTPUT.PUT_LINE('사원수 : ' || TO_CHAR(emp_list.cnt));
 	END LOOP;
END;

 

커서에 파라미터를 전달해서 사용할 수 있다.

DECLARE
 CURSOR emp_list(v_deptno  emp.deptno%TYPE) IS
 	SELECT  ename 
	FROM      emp
 	WHERE   deptno = v_deptno;
BEGIN
 DBMS_OUTPUT.PUT_LINE('** 입력한 부서 직원** '); -- 패러미터변수의값을전달(OPEN될때값전달)
 FOR emplst IN emp_list(10) LOOP 
	DBMS_OUTPUT.PUT_LINE(‘부서번호10 : ' || emplst.ename);
 END LOOP;
 FOR emplst IN emp_list(20) LOOP 
	DBMS_OUTPUT.PUT_LINE(‘부서번호20 : ' || emplst.ename);
 END LOOP;
END;

 

 

예외처리

예외 설명 처리
미리 정의된 오라클 서버 예외 PL/SQL에서 자주 발생하는 약 20개의 오류 선언할 필요 없음. 발생시 자동 트랩
미리 정의되지 않은 오라클 서버 예외 미리 정의된 오라클 서버 예외를 제외한 모든 오류 선언부에서 선언해야하고 발생시 자동 트랩
사용자 정의 예외 개발자가 정한 조건에 만족하지 않을 경우 발생하는 오류 선언부에서 선언하고 실행부에서 RAISE문을 사용하여 발생
DECLARE
 	not_null_test  EXCEPTION; -- 단계1(미리 정의되지 않은 예외
 	/* not_null_test는 선언된 예외 이름-1400 Error 처리번호는표준Oracle Server Error 번호 */
 	PRAGMA EXCEPTION_INIT(not_null_test, -1400);-- 단계2
    --사용자 정의 예외
    user_define_error EXCEPTION; -- 단계 1
 	cnt NUMBER;
BEGIN
	-- empno를 입력하지않아서NOT NULL 에러발생
	INSERT INTO emp(ename, deptno) VALUES('tiger', 30);
    IF cnt < 5 THEN-- RAISE문을 사용하여 직접적으로예외발생
    	RAISE user_define_error;
    END IF;
    
 	EXCEPTION
   		WHEN TOO_MANY_ROWS THEN --미리 정의된 예외
 			DBMS_OUTPUT.PUT_LINE('TOO_MANY_ROWS에러 발생');
		WHEN not_null_test  THEN -- 단계 3
 			DBMS_OUTPUT.PUT_LINE('not null 에러 발생 ');
        WHEN user_define_error THEN
 			RAISE_APPLICATION_ERROR(-20001, '사원 부족’);
        WHEN OTHERS THEN --항상 마지막에 위치
			DBMS_OUTPUT.PUT_LINE('기타 에러 발생');
 END;

 

'database' 카테고리의 다른 글

데이터베이스 프로그래밍 과제 / 최신 데이터베이스  (0) 2025.06.11
데이터베이스 성능 향상[Index]  (0) 2025.06.11
Transaction(트랜잭션)  (0) 2025.06.11
PL/SQL (프로시저, 함수, 트리거)  (0) 2025.06.11
PL/SQL [Oracle]  (0) 2025.06.10
'database' 카테고리의 다른 글
  • 데이터베이스 성능 향상[Index]
  • Transaction(트랜잭션)
  • PL/SQL (프로시저, 함수, 트리거)
  • PL/SQL [Oracle]
chanhuy
chanhuy
  • chanhuy
    차늬
    chanhuy
  • 전체
    오늘
    어제
    • 분류 전체보기 (34)
      • algorithm (9)
      • Python (2)
      • database (8)
      • csts (3)
      • Operating System (0)
      • 오픈소스SW (1)
      • Git & Github (4)
      • 프로젝트 회고 (3)
      • 정보처리기사 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    dynamic programming
    프로젝트후기
    greedy
    알고리즘
    Python
    pl/sql
    recursion
    오픈소스SW
    Reduction
    backtracking
    Git
    graph algorithms
    algorithm
    index
    D&C
    COMMIT
    시간복잡도
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
chanhuy
PL/SQL 커서(Cursor)와 예외처리
상단으로

티스토리툴바