17. PL/SQL - 경영정보학과mis.mju.ac.kr/~shpark/2010fall/advdb/PL_… · PPT file · Web view · 2016-07-25pl/sql 개 요 pl/sql의 필요성 및 특징 sql의 특징 4세대

Post on 19-Mar-2018

223 Views

Category:

Documents

5 Downloads

Preview:

Click to see full reader

Transcript

PL/SQL

2

개 요 PL/SQL 의 필요성 및 특징

SQL 의 특징 4 세대 언어 간단하고 적은 수의 명령어를 가짐 사용자들에게 알고리즘을 은닉함

C 나 COBOL 등의 특징 3 세대 언어 절차적인 알고리즘으로 구현

위와 같은 각각의 언어들의 특징들을 사용하기 위하여 사용하게 된다 . 즉 3 세대 언어에서 가능한 절차적 구성이 4 세대 언어에서 필요할 때가 있는데 , 이런 경우를 위하여 PL/SQL이라는 언어가 도입

Oracle 에서의 PL/SQL 은 절차적프로그래밍을 할 수 있도록 SQL 을 확장

3

PL/SQL 의 기초 문자집합

대문자 A – Z, 소문자 a – z 숫자 0 – 9 기호 ( ) + - * / < > = ! ~ ^ ; : . @ % , “ # $ & _ | { } [ ] ? 탭 , 스페이스 , 캐리지 리턴

식별자 상수 , 변수 , 예외 사항 , 커서 , 서브 프로그램 등을 포함하는 PL/SQL

프로그램 아이템과 유닛들의 이름 문자로 시작하고 , 숫자 , 달러 기호 ($), 언더스코어 (_), 숫자기호 (#)

등을 조합하여 사용 예제

money$$$tree, SN#, try_again ( 허용됨 ) mine&yours, debit-amout, on/off, user id( 허용되지 않음 ) lastname, LastName, LASTNAME( 같은 것으로 간주 )

4

PL/SQL 의 기초 키워드

키워드 (keyword) 라고 불리는 식별자들은 PL/SQL 에서 특별한 의미를 가지고 있기 때문에 , 상수와 변수 또는 커서 등에 대한 이름으로 사용할 수 없음 ( 통상적으로 키워드는 가독성을 위하여 대문자로 사용 )

예제 DECLARE begin number ( 키워드 begin 을 사용하므로 에러 )

주석한 줄 주석을 사용

두줄 주석을 사용

5

-- 처리의 시작

SELECT sal INTO salary FROM emp

WHERE empno = emp_id; -- 현재 월급을 가져옴

bonus := salary * 0.15 – 보너스의 계산

/* 등급이 우수한 직원들에게 15% 의 보너스를 두고 , 그 외에는 보너스를 주지 않음 */

IF rating > 90 THEN

bonus := salary * 0.15 /* 월급에 기본을 두고 보너스 계산 */

ELSE

bonus := 0;

END IF;

6

PL/SQL 의 기초 데이타 타입

숫자타입BINARY_INTEGER : -2,147,483,647 ~

2,147,483,647 사이의 정수– SUBTYPE

» NATURAL : 음수를 제외한 정수 (0 ~ 2,147,483,647)» POSITIVE : 양의 정수 (1 ~ 2,147,483,647)» SIGNTYPE : -1, 0 , 1 의 값만 가짐

7

NUMBER : 10-130 ~ 10125 사이의 고정소수점이나 부동소수점 수– SUBTYPE

» DEC, DECIMAL, NUMERIC : 최대 38 자리의 고정 소수점 수» DOUBLE PRECISION, FLOAT: 최대 126 자리 이진부동소수점 수» REAL : 최대 63 자리 이진 부동 소수점 수» INTEGER, INT, SMALLINT : 최대 38 자리의 정수

PLS_INTEGER : -231 ~ 231 사이의 정수

8

PL/SQL 의 기초 데이타 타입

문자타입CHAR : 고정 길이의 문자열을 저장 . 32,767 바이트까지

저장가능– 사용예 : CHAR[( 길이 )]

VARCHAR2: 가변길이문자열을 저장 . 32,767 바이트까지 저장가능

– 사용예 : VARCHAR2( 최대길이 )LONG, LONG RAW : 가변길이 문자열을 저장 .RAW : 이진 데이타나 이진 문자열을 저장하기 위해 사용

– 사용예 : RAW( 최대크기 )

9

기타타입BOOLEAN : 논리적인 참 , 거짓 , 널값을 저장하기 위해

사용 . 오직 논리 연산만 허용 .DATE : 날짜와 시간을 저장하기 위해 DATE 타입을 사용 .

DATE 타입의 값은 자정 이후의 시간을 초 단위도 포함하여 저장 .

10

PL/SQL 의 구조 PL/SQL

블록 구조의 언어삽입 SQL 문을 지원프로시저와 함수의 선언조건 , 반복 과 같은 제어문 변수 선언

PL/SQL 블록선언부 ( 생략가능 )실행부 ( 필수 )예외 상황 처리부 ( 생략가능 )

11

선언부

실행부

예외 상황 처리부

Declare

Begin

Exception

End;

생략가능

생략가능

필수

12

선언부 변수선언

한줄에 하나의 변수만 선언 가능

DECLARE v_job VARCHAR2(9); v_count BINARY_INTEGER := 0; v_total_sal NUMBER(9,2) := 0; v_hiredate DATE; v_valid BOOLEAN := FALSE; BEGIN

13

DEFAULT 의 사용:= 연산자 대신에 키워드 DEFAULT 를 사용하여 변수에 초기값을 할당

DECLARE blood_type CHAR := ‘O’; -- blood_type CHAR DEFAULT ‘O’BEGIN

14

선언부 변수선언

NOT NULL 의 사용 : 초기값을 할당하는 것 이외에 , NOT NULL 제약을 변수에 부여

%TYPE 속성의 사용 v_student_name 은 이미 선언된 변수 v_name 과 동일한 VARCHA

R2(10) 으로 선언

DECLARE v_emp_id NUMBER(4) NOT NULL := 9999; -- 적합 v_dept_no NUMBER(2) NOT NULL; -- 에러BEGIN

DECLARE v_name VARCHAR2(10); v_student_name v_name%TYPE; v_st_name v_name%TYPE := ‘scott’BEGIN

15

선언부 변수선언

%ROWTYPE 속성의 사용Student 테이블이 두 애트리뷰트 name, grade 를 포함하고

있을 때 , 아래 선언의 결과로 v_student_rec 와 v_stu_rec변수는 student 테이블의 레코드와 동일한 복합 변수로 선언

다음과 같은 SELECT 명령에서의 v_stu_rec 와 같이 %ROWTYPE 속성은 SELECT 명령에서 행을 가져 올 때 매우 유용

16

DECLARE v_student_rec student%ROWTYPE; v_stu_rec student%ROWTYPE; BEGIN v_student_rec.name := ‘JOHNSON’; v_student_rec.grade := ‘A’; ⋮ SELECT * INTO v_stu_rec FROM student WHERE ... ⋮END;

17

선언부 상수선언

키워드 CONSTANT 를 명시하고 반드시 기본값을 지정DECLARE c_num CONSTANT NUMBER := 100;BEGIN c_num := 200; -- 에러END;

18

선언부커서 선언

커서 : SQL 명령을 실행할 때 , 오라클 서버는 명령이 파싱 되고 , 실행되는 메모리의 영역을 오픈하는데 이 영역을 커서 (Cursor) 라고 함 .

하나의 행만 반환하는 질의를 포함한 모든 데이타 조작 SQL 명령에 대해서는 묵시적으로 커서를 선언하고 , 하나 이상의 행을 반환하는 SELECT 명령에 대해서는 사용자가 명시적으로 커서를 선언

19

구 분 묵시적 커서 명시적 커서생성 및 관리 DBMS 사용자선 언 SELECT, DML 문에 의해 DECLARE

CURSOR C1 IS SELECT 명령 ;BEGIN

속 성 %NotFound%Found%ISOpen( 항상 False)%RowCount

%NotFound%Found%ISOpen%RowCount

20

선언부 커서선언

예제c1, c2 라는 이름의 두개의 커서를 선언c1 은 emp 테이블에서 월급이 2000 보다 많은 직원들의

사원번호와 이름 , 직업 , 웕급을 가져오는 커서c2 는 dept 테이블에서 부서번호가 10 번인 부서의 레코드를

가져 오는 커서이고 반환 타입은 dept 테이블에 속한 모든 열들을 가져오도록 %ROWTYPE 속성을 이용

21

DECLARE CURSOR c1 IS SELECT empno, ename, job, sal FROM emp; WHERE sal > 2000; CURSOR c2 RETURN dept%ROWTYPE IS SELECT * FROM dept WHERE deptno = 10; BEGIN

22

실행부 SQL 명령

SELECT 명령에서 INTO 절을 사용하여 SELECT 명령에 의해 반환되는 결과를 PL/SQL 의 변수에 저장가능아래의 예제는 s_dept 테이블에서 id 가 10 인 부서이름

name 을 검색하여 그 값을 v_name 에 지정DECLARE v_name s_dept.name%TYPE;BEGIN SELECT name INTO v_name FROM s_dept WHERE id = 10; ⋮END;

23

실행부 SQL 명령

INSERT, UPDATE, DELETE SQL 명령으로 데이타를 삽입 , 갱신 , 삭제 가능BEGIN INSERT INTO emp(empno, ename) VAULES(8288, ‘TEST’); ⋮ UPDATE dept SET dname = ‘EDUCATION’ WHERE deptno = 10; ⋮ DELETE FROM emp WHERE deptno = 20; ⋮END;

24

실행부 IF 문

IF – THEN

IF – THEN – ELSE

IF 조건 THEN

문 ;

END IF;

IF 조건 THEN

문 1;

ELSE

문 2;

END IF;

25

IF – THEN – ELSIF

IF 조건 1 THEN

문 1;

ELSEIF 조건 2 THEN

문 2;

[ELSEIF 조건 3 THEN

문 3;]

[ELSE

문 4;]

END IF;

26

실행부 반복 실행문

반복실행문은 명령들을 여러 번 반복해서 수행 반복 실행문 : LOOP, WHILE, FOR 문

LOOP

27

LOOP

EXIT WHEN 조건 ;

END LOOP;

28

실행부 반복 실행문

WHILE 루프WHILE 조건 LOOP

END LOOP;

29

실행부 반복 실행문

FOR 루프FOR 루프변수 IN [REVERSE] 하한 .. 상한 LOOP

END LOOP;

30

실행부 GOTO 문

PL/SQL 에서는 GOTO 문을 이용하여 무조건 분기실행할 때 GOTO 문은 제어를 레이블이 있는 위치로 이동GOTO 레이블 ;

<< 레이블 >>

BEGIN

GOTO insert_row;

<<insert_row>>

INSERT INTO emp VALUES …

END;

31

실행부 NULL 문

NULL 문은 아무 일도 하지 않는다는 사실을 명시적으로 나타냄IF rating > 90 THEN

compute_bonus(emp_id);

ELSE

NULL;

END IF;

32

실행부 커서의 조작

커서는 OPEN, FETCH, CLOSE 문을 이용하여 제어OPEN 문은 커서와 관련된 질의를 실행하고 , 커서가 반환 한 값 중에서 첫 번째 행을 지시FETCH 문은 현재 행을 읽어 들인 후 , 다음 행으로 커서를 이동시킴커서를 종료할 때는 CLOSE 문을 사용커서의 오픈DECLARE

CURSOR c1 IS SELECT empno, ename, job, sal FROM emp WHERE sal > 2000; ...BEGIN OPEN c1; ... END;

33

실행부 커서의 조작

데이타의 FETCHFETCH 명령은 결과 집합에서 한 번에 한 행만을 가져옴한 번의 FETCH 후에 커서는 결과 집합에서 다음 행을 지시 FETCH c1 INTO my_empno, my_ename, my_deptno;

BEGIN

LOOP

FETCH c1 INTO my_record;

EXIT WHEN c1%NOTFOUND;

… -- 데이타 레코드의 처리END LOOP

END;

34

실행부 커서의 조작

데이타의 FETCHFOR LOOP 을 이용한 예제

35

실행부 커서의 조작

CLOSE 명령은 커서를 비활성화 결과 집합이 정의 되지 않은 상태로 만듬 종료된 커서에 대한 연산은 미리 정의된 예외인 INVALID_CURSOR 를

발생

DECLARE

CURSOR c1 IS -- 커서의 선언SELECT …

BEGIN

OPEN c1; -- 커서 오픈…

FETCH c1 INTO …; -- 데이타의 FETCH

CLOSE c1; -- 커서 종료END;

36

실행부 커서의 조작

명시적 커서의 속성 %FOUND

– 커서를 오픈했을 때 첫번째 FETCH 가 실행되기 전에 %FOUND 는 NULL 값

BEGIN

LOOP

FETCH c1 INTO my_ename, my_sal, my_hiredate;

IF c1%FOUND THEN -- FETCH 의 성공

… -- 데이타의 처리

ELSE

EXIT;

END IF;

END LOOP;

END;

37

실행부 커서의 조작

%ISOPEN– %ISOPEN 은 커서가 오픈되었으면 참 , 그렇지 않으면 거짓BEGIN

IF c1%ISOPEN THEN -- 커서가 오픈된 상태

ELSE

OPEN c1;

END IF

END;

38

실행부 커서의 조작

%NOTFOUND– %NOTFOUND 는 %FOUND 와 논리적으로 반대 의미– 가장 최근에 FETCH 가 행을 반환하면 %NOTFOUND 는 거짓– 가장 최근의 FETCH 가 행을 반환하는데 실패하면 참BEGIN

LOOP

FETCH c1 INTO my_ename, my_sal, my_hiredate;

EXIT WHEN c1%NOTFOUND;

END LOOP;

END;

39

실행부 커서의 조작

%ROWCOUNT– 커서를 오픈했을 때 , %ROWCOUNT 는 0– 첫번째 FETCH 이전에는 %ROWCOUNT 는 0– %ROWCOUNT 는 계 속 가져온 행들의 수를 기록– FETCH 가 행을 가져오는데 성공할 때마다 , %ROWCOUNT 의 값은 하나씩 증가

BEGIN

LOOP

FETCH c1 INTO my_ename, my_sal, my_hiredate;

IF c1%ROWCOUNT > 10 THEN

… -- 데이타의 처리

END IF;

END LOOP;

END;

40

예외 상황 처리부 예외 상황 사용의 장점

에러 처리 루틴을 분리함으로써 가독성을 향상시킴안정성을 향상 시킴BEGIN

SELECT ...SELECT ...SELECT ......

EXCEPTIONWHEN NO_DATA_FOUND THEN

-- 모든 ‘ no data found’ 에러를 처리

41

예외 상황 처리부 미리 정의된 예외 상황예외 상황 Orac

le Error

SQL CODE값

내 용

No_Data_Found

ORA-0140

3

+100 행이 한건도 반환되지 않음

Too_Many_Rows

ORA-0142

2

-1422 행이 두개 이상 반환

Zero_Divide ORA-0147

6

-1476 제수가 0 일 때

Invalid_Number

ORA-0172

2

-1722 숫자 형태가 아닌 값을 숫자변수에 대입할 때Login_Denied

ORA-0101

7

-1017 잘못된 userid/password 로 접속을 시도 했을 때

Not_Logged_On

ORA-0101

2

-1012 오라클에 접속하지 않고 PL/SQL 을 수행했을 때

Others 위에서 명세되지 않은 예외 상황

42

예외 상황 처리부 사용자 정의 예외 상황

예외 상황의 선언

예외 상황의 명시적인 발생미리 정의된 예외 상황과는 달리 RAISE 명령에 의해 명시적으로 발생

DECLAREpast_due

EXCEPTION;

RAISE out_of_stock;

43

예외 상황 처리부 예외 상황 전파

에러 발생시 가장 가까운 예외 상황 처리부를 찾아 실행DECLARE temp NUMBER; v_salary NUMBER;BEGIN SELECT salary INTO v_salary FROM s_emp WHERE id = 1; DECLARE v_start_date DATE; v_date DATE; BEGIN SELECT start_date INTO v_date FROM s_emp WHERE id = 99; v_date := v_start_date + 15; EXCEPTION WHEN No_Data_Found THEN message(' 데이타 없음 '); END; temp := v_salary * 12;EXCEPTION WHEN Too_Many_Rows THEN message(' 중복 데이타 ');END;

44

예외 상황 처리부 예외 상황 전파

45

서브프로그램 프로시저

구조

저장 프로시저 : 재사용 가능

PROCEDURE 프로시저이름 [( 매개변수 1, ... [, 매개변수 n])] IS

[ 변수선언 ]BEGIN 실행부 ;[ 예외상황 처리부 ]END [ 프로시저이름 ];

CREATE [OR REPLACE] PROCEDURE 프로시저이름[( 매개변수 1, ... [, 매개변수 n])] IS

[ 변수선언 ]BEGIN 실행부 ;[ 예외상황 처리부 ]END [ 프로시저이름 ];

46

서브프로그램 프로시저raise_salary(7844, 1000); 1. emp_audit

테이블 생성

2. emp_audit테이블의

데이타 확인

47

서브프로그램 프로시저

raise_salary 프로시저를 포함한 PL/SQL 블록을 실행한 후 , emp 테이블에서 결과를 다시 확인

3. raise_salary프로시저 예제실행화면

48

서브프로그램 프로시저

raise_salary(8528, 100) - empno 가 8528 인 emp 행이 없기 때문에 emp_audit 테이블에 에러 메시지가 저장

4. emp 테이블의 데이타와

에러메시지 확인

49

서브프로그램 프로시저

프로시저를 오라클 데이타베이스에 저장하여 , 저장 프로시저로 만들면 영구적으로 재사용이 가능CREATE [OR REPLACE] 명령을 사용하여 프로시저를 저장 OR REPLACE 절은 동일한 이름의 프로시저가 이미 저장되어 있다면 그 프로시저의 내용을 지금 작성 하는 프로시저로 변경하라는 의미 CREATE [OR REPLACE] PROCEDURE 프로시저 이름

[( 인자 1, … [, 인자 n])] IS

[ 변수선언 ]

BEGIN

실행부 ;

[ 예외상황 처리부 ]

END [ 프로시저 이름 ];

50

서브프로그램 프로시저

앞의 예제

51

서브프로그램 프로시저

자신이 어떤 프로시저를 만들었는지 알고 싶다면 user_objects 데이타 딕셔너리에 질의

저장 프로시저의 인자에 대한 정보를 검색해 보고 싶으면 DESC 명령을 사용

52

서브프로그램 함수

프로시저와 유사프로시저와의 차이점 : 함수는 미리 정의된 데이타 타입의 값을 반환FUNCTION 함수이름 [( 인자 1, … [, 인자 n])]

RETURN 함수 _ 데이타 타입 IS

[ 변수선언 ]

BEGIN

실행부 ;

[ 예외 상황 처리부 ]

END [ 함수이름 ];

53

서브프로그램 함수

직업이 title 이고 봉급이 salary 일 때 , sals 테이블에 기록된 최소 봉급과 최대 봉급 범위에 salary 가 해당하는지 여부를 나타내는 예제

함수 이름 sal_ok 는 RETURN 명령에 의해 Boolean 값을 가짐FUNCTION sal_ok(salary REAL, title VARCHAR2)

RETURN BOOLEAN IS

min_sal REAL;

max_sal REAL;

BEGIN

SELECT low_sal, high_sal INTO min_sal, max_sal

FROM sals

WHERE job = title;

RETURN (salary >= min_sal) AND (salary <= max_sal);

END sal_ok;

54

서브프로그램 함수

1. sals 테이블생성

2. sals 테이블에데이타 입력

55

서브프로그램 함수

3. sal_ok 함수 예제의 실행

56

서브프로그램 함수

4. 저장함수sal_ok 의 생성

5. 저장함수에대한 정보 보기

57

서브프로그램 서브 프로그램의 인자

서브 프로그램에서 사용되는 인자들의 유형 IN( 디폴트 ) , OUT, IN OUT 함수의 인자 유형으로 OUT, IN OUT 을 사용 – 바람직하지 않음

IN IN 유형으로 정의된 인자의 특징

– 인자값을 함수나 프로시저에 전달할 뿐 , 값을 지정 하거나 값을 반환할 수 없음– 확인 예제

PROCEDURE debit_account (acct_id IN INTEGER, amount IN REAL) IS

minimum_purchase CONSTANT REAL := 10.0;

service_charge CONSTANT REAL := 0.50;

BEGIN

IF amount < minimum_purchase THEN

amount := amount + service_charge;

-- 컴파일 에러 발생END IF;

END;

58

서브프로그램 서브 프로그램의 인자

OUT값을 참조하지 않고 , 서브 프로그램을 호출한 PL/SQL 문에 값을 반환하는데 사용확인예제PROCEDURE calc_bonus (emp_id IN INTEGER, bonus OUT REAL) IS

hire_date DATE;

BEGIN

SELECT sal * 0.10, hiredate INTO bonus, hire_date

FROM emp

WHERE empno = emp_id;

IF MONTHS_BETWEEN(SYSDATE, hire_date) > 60 THEN

bonus := bonus + 500; -- 에러발생

END IF;

END;

59

서브프로그램 서브 프로그램의 인자

IN OUT 인자값을 서브프로그램에 전달하거나 호출 PL/SQL 문에 값을 반환시 사용

PROCEDURE calc_bonus (emp_id IN INTEGER, bonus IN OUT REAL) IS

hire_date DATE;

bonus_missing EXCEPTION;

BEGIN

SELECT sal * 0.10, hiredate INTO bonus, hire_date

FROM emp

WHERE empno = emp_id;

IF bonus IS NULL THEN

RAISE bonus_missing;

END IF;

IF MONTHS_BETWEEN(sysdate, hire_date) > 60 THEN

bonus := bonus + 500;

END IF;

EXCEPTION

WHEN bonus_missing THEN

END calc_bonus;

60

실행부 커서의 조작

커서는 OPEN, FETCH, CLOSE 문을 이용하여 제어OPEN 문은 커서와 관련된 질의를 실행하고 , 커서가 반환 한 값 중에서 첫 번째 행을 지시FETCH 문은 현재 행을 읽어 들인 후 , 다음 행으로 커서를 이동시킴커서를 종료할 때는 CLOSE 문을 사용커서의 오픈

61

DECLARE CURSOR c1 IS SELECT empno, ename, job, sal FROM emp WHERE sal > 2000; ...BEGIN OPEN c1; ... END;

62

실행부 커서의 조작

데이타의 FETCHFETCH 명령은 결과 집합에서 한 번에 한 행만을 가져옴한 번의 FETCH 후에 커서는 결과 집합에서 다음 행을 지시

63

FETCH c1 INTO my_empno, my_ename, my_deptno;

BEGIN

LOOP

FETCH c1 INTO my_record;

EXIT WHEN c1%NOTFOUND;

… -- 데이타 레코드의 처리END LOOP

END;

64

실행부 커서의 조작

데이타의 FETCHFOR LOOP 을 이용한 예제

65

66

실행부 커서의 조작

CLOSE 명령은 커서를 비활성화 결과 집합이 정의 되지 않은 상태로 만듬 종료된 커서에 대한 연산은 미리 정의된 예외인 INVALID_CURSOR 를

발생

67

DECLARE

CURSOR c1 IS -- 커서의 선언SELECT …

BEGIN

OPEN c1; -- 커서 오픈…

FETCH c1 INTO …; -- 데이타의 FETCH

CLOSE c1; -- 커서 종료END;

68

실행부커서의 조작

명시적 커서의 속성%FOUND

– 커서를 오픈했을 때 첫번째 FETCH 가 실행되기 전에 %FOUND 는 NULL 값

69

BEGIN

LOOP

FETCH c1 INTO my_ename, my_sal, my_hiredate;

IF c1%FOUND THEN -- FETCH 의 성공

… -- 데이타의 처리

ELSE

EXIT;

END IF;

END LOOP;

END;

70

실행부커서의 조작

%ISOPEN– %ISOPEN 은 커서가 오픈되었으면 참 , 그렇지

않으면 거짓

71

BEGIN

IF c1%ISOPEN THEN -- 커서가 오픈된 상태

ELSE

OPEN c1;

END IF

END;

72

실행부커서의 조작

%NOTFOUND– %NOTFOUND 는 %FOUND 와 논리적으로 반대 의미– 가장 최근에 FETCH 가 행을 반환하면 %NOTFOUND 는 거짓– 가장 최근의 FETCH 가 행을 반환하는데 실패하면 참

73

BEGIN

LOOP

FETCH c1 INTO my_ename, my_sal, my_hiredate;

EXIT WHEN c1%NOTFOUND;

END LOOP;

END;

74

실행부커서의 조작

%ROWCOUNT– 커서를 오픈했을 때 , %ROWCOUNT 는 0– 첫번째 FETCH 이전에는 %ROWCOUNT 는 0– %ROWCOUNT 는 계속 가져온 행들의 수를 기록– FETCH 가 행을 가져오는데 성공할 때마다 , %ROWCOUNT 의

값은 하나씩 증가

75

BEGIN

LOOP

FETCH c1 INTO my_ename, my_sal, my_hiredate;

IF c1%ROWCOUNT > 10 THEN

… -- 데이타의 처리

END IF;

END LOOP;

END;

76

예외 상황 처리부 예외 상황 사용의 장점

에러 처리 루틴을 분리함으로써 가독성을 향상시킴안정성을 향상 시킴

BEGINSELECT ...SELECT ...SELECT ......

EXCEPTIONWHEN NO_DATA_FOUND THEN

-- 모든 ‘ no data found’ 에러를 처리

77

예외 상황 처리부 미리 정의된 예외 상황

78

예외 상황 Oracle Error

SQL CODE 값 내 용

No_Data_Found

ORA-01403

+100 행이 한건도 반환되지 않음Too_Many_Rows

ORA-01422

-1422 행이 두개 이상 반환Zero_Divide ORA-

01476-1476 제수가 0 일 때

Invalid_Number

ORA-01722

-1722 숫자 형태가 아닌 값을 숫자변수에 대입할 때Login_Denied ORA-

01017-1017 잘못된 userid/password 로

접속을 시도 했을 때

Not_Logged_On

ORA-01012

-1012 오라클에 접속하지 않고 PL/SQL을 수행했을 때Others 위에서 명세되지 않은 예외

상황

79

예외 상황 처리부 사용자 정의 예외 상황

예외 상황의 선언

예외 상황의 명시적인 발생미리 정의된 예외 상황과는 달리 RAISE 명령에 의해 명시적으로 발생

DECLAREpast_due

EXCEPTION;

RAISE out_of_stock;

80

예외 상황 처리부 예외 상황 전파

에러 발생시 가장 가까운 예외 상황 처리부를 찾아 실행

81

DECLARE temp NUMBER; v_salary NUMBER;BEGIN SELECT salary INTO v_salary FROM s_emp WHERE id = 1; DECLARE v_start_date DATE; v_date DATE; BEGIN SELECT start_date INTO v_date FROM s_emp WHERE id = 99; v_date := v_start_date + 15; EXCEPTION WHEN No_Data_Found THEN message(' 데이타 없음 '); END; temp := v_salary * 12;EXCEPTION WHEN Too_Many_Rows THEN message(' 중복 데이타 ');END;

82

예외 상황 처리부 예외 상황 전파

83

84

서브프로그램 프로시저

구조PROCEDURE 프로시저이름 [( 매개변수 1, ... [, 매개변수n])] IS

[ 변수선언 ]BEGIN 실행부 ;[ 예외상황 처리부 ]END [ 프로시저이름 ];

85

CREATE [OR REPLACE] PROCEDURE 프로시저이름[( 매개변수 1, ... [, 매개변수 n])] IS

[ 변수선언 ]BEGIN 실행부 ;[ 예외상황 처리부 ]END [ 프로시저이름 ];

저장 프로시저 : 재사용 가능

86

서브프로그램 프로시저

raise_salary(7844, 1000);

1. emp_audit테이블 생성

87

2. emp_audit테이블의

데이타 확인

88

서브프로그램 프로시저

raise_salary 프로시저를 포함한 PL/SQL 블록을 실행한 후 , emp 테이블에서 결과를 다시 확인

89

3. raise_salary프로시저 예제실행화면

90

서브프로그램 프로시저

raise_salary(8528, 100) - empno 가 8528 인 emp 행이 없기 때문에 emp_audit 테이블에 에러 메시지가 저장

91

4. emp 테이블의 데이타와

에러메시지 확인

92

서브프로그램 프로시저

프로시저를 오라클 데이타베이스에 저장하여 , 저장 프로시저로 만들면 영구적으로 재사용이 가능CREATE [OR REPLACE] 명령을 사용하여 프로시저를 저장 OR REPLACE

동일한 이름의 프로시저가 이미 저장되어 있다면 그 프로시저의 내용을 지금 작성 하는 프로시저로 변경하라는 의미

93

CREATE [OR REPLACE] PROCEDURE 프로시저 이름[( 인자 1, … [, 인자 n])] IS

[ 변수선언 ]BEGIN

실행부 ;[ 예외상황 처리부 ]END [ 프로시저 이름 ];

94

서브프로그램 프로시저

앞의 예제

95

서브프로그램 프로시저

자신이 어떤 프로시저를 만들었는지 알고 싶다면 user_objects 데이타 딕셔너리에 질의

96

저장 프로시저의 인자에 대한 정보를 검색해 보고 싶으면 DESC 명령을 사용

97

서브프로그램 함수

프로시저와 유사프로시저와의 차이점 : 함수는 미리 정의된 데이타 타입의 값을 반환

FUNCTION 함수이름 [( 인자 1, … [, 인자 n])]RETURN 함수 _ 데이타 타입 IS

[ 변수선언 ]BEGIN

실행부 ;[ 예외 상황 처리부 ]END [ 함수이름 ];

98

서브프로그램함수

직업이 title 이고 봉급이 salary 일 때 , sals 테이블에 기록된 최소 봉급과 최대 봉급 범위에 salary 가 해당하는지 여부를 나타내는 예제

함수 이름 sal_ok 는 RETURN 명령에 의해 Boolean 값을 가짐

99

FUNCTION sal_ok(salary REAL, title VARCHAR2)

RETURN BOOLEAN IS

min_sal REAL;

max_sal REAL;

BEGIN

SELECT low_sal, high_sal INTO min_sal, max_sal

FROM sals

WHERE job = title;

RETURN (salary >= min_sal) AND (salary <= max_sal);

END sal_ok;

100

서브프로그램 함수 1. sals

테이블생성

101

2. sals 테이블에데이타 입력

102

서브프로그램 함수

3. sal_ok 함수 예제의 실행

103

서브프로그램 함수 4. 저장함수

sal_ok 의 생성

104

5. 저장함수에대한 정보 보기

105

서브프로그램서브 프로그램의 인자

서브 프로그램에서 사용되는 인자들의 유형 IN( 디폴트 ) , OUT, IN OUT 함수의 인자 유형으로 OUT, IN OUT 을 사용 – 바람직하지

않음IN

IN 유형으로 정의된 인자의 특징– 인자값을 함수나 프로시저에 전달할 뿐 , 값을 지정 하거나 값을

반환할 수 없음– 확인 예제

106

PROCEDURE debit_account (acct_id IN INTEGER, amount IN REAL) IS

minimum_purchase CONSTANT REAL := 10.0;service_charge CONSTANT REAL := 0.50;

BEGIN…IF amount < minimum_purchase THEN

amount := amount + service_charge;-- 컴파일 에러 발생

END IF;END;

107

서브프로그램서브 프로그램의 인자

OUT값을 참조하지 않고 , 서브 프로그램을 호출한

PL/SQL 문에 값을 반환하는데 사용확인예제

108

PROCEDURE calc_bonus (emp_id IN INTEGER, bonus OUT REAL) IS

hire_date DATE;

BEGIN

SELECT sal * 0.10, hiredate INTO bonus, hire_date

FROM emp

WHERE empno = emp_id;

IF MONTHS_BETWEEN(SYSDATE, hire_date) > 60 THEN

bonus := bonus + 500; -- 에러발생

END IF;

END;

109

서브프로그램서브 프로그램의 인자

IN OUT인자값을 서브프로그램에 전달하거나 호출 PL/SQL 문에

값을 반환시 사용

110

PROCEDURE calc_bonus (emp_id IN INTEGER, bonus IN OUT REAL) IS

hire_date DATE;

bonus_missing EXCEPTION;

BEGIN

SELECT sal * 0.10, hiredate INTO bonus, hire_date

FROM emp

WHERE empno = emp_id;

IF bonus IS NULL THEN

RAISE bonus_missing;

END IF;

IF MONTHS_BETWEEN(sysdate, hire_date) > 60 THEN

bonus := bonus + 500;

END IF;

EXCEPTION

WHEN bonus_missing THEN

END calc_bonus;

top related