일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 백준 자바
- 오라클 제약조건
- JAVA공부
- 백준 2437
- 코딩
- 제약조건 설정
- 도서관 관리
- 오라클
- oracle constraints
- 자바 알고리즘
- ORACLE JOIN
- 자바
- 오라클 그룹 함수
- 제약조건 확인
- 백준 저울
- 자바 예제
- java 도서관관리프로그램
- 오라클 인라인뷰
- java프로젝트
- 오라클 쿼리 함수
- java실습
- 백준 문제
- 자료구조
- java 백준
- 도서관관리프로그램
- 오라클 쿼리문
- java
- 자바 자료구조
- JAVA 예제
- 오라클 기본 쿼리
- Today
- Total
DEVELOPER NOMAD
[오라클 사용자 함수] ORACLE Stored Function 실습 본문
[오라클 사용자 함수] ORACLE Stored Function 실습
DEVELOPER NOMAD 2019. 1. 11. 15:25//*****************************************
-- Stored Function(사용자 함수)
- 스토어드 함수는 시스템 함수처럼 쿼리에서 호출하거나 저장 프로시저처럼 EXECUTE 문을 통해 실행할 수 있다.
- 패키지 내에서 Function은 중복 정의가 가능하다.
----------------------------------------------
-- 형식(인수나 RETURN 에서는 자료형의 크기를 명시하지 않는다.)
CREATE [OR REPLACE] FUNCTION 함수이름
[(
매개변수1 IN 자료형,
매개변수2 IN 자료형
)]
RETURN datatype;
IS
[변수의 선언]
BEGIN
.............
RETURN (값);
[EXCEPTION]
.............
END;
/
----------------------------------------------
-- 함수 목록 확인
SELECT object_name FROM user_procedures;
----------------------------------------------
-- EXECUTE 또는 CALL를 이용한 함수 실행
1. EXECUTE
EXEC :바인딩변수 := 함수명([인수, 인수]);
PRINT :바인딩변수
2. CALL
CALL 함수명([인수, 인수]) INTO :바인딩변수;
PRINT :바인딩변수
----------------------------------------------
-- 합구하기
CRTEATE OR REPLACE FUNCTION fnSum
(
n IN NUMBER
)
RETURN NUMBER
IS
s NUMBER := 0;
BEGIN
FOR i IN 1..n LOOP
s := s + i;
END LOOP;
RETURN s;
END;
/
SELECT fnSum(100) FROM dual;
-- 성별 구하기(DECODE, CASE 는 PL/SQL 사용 불가)
CRTEATE OR REPLACE FUNCTION fnGender
(
ssn IN VARCHAR2
)
RETURN VARCHAR2
IS
s VARCHAR2(6) := '여자';
BEGIN
IF LENGTH(ssn) != 14 THEN
RAISE_APPLICATION_ERROR(-20001, '주민번호는 14자리');
END IF;
IF MOD(SUBSTR(ssn, 8, 1), 2) = 1 THEN
s := '남자';
END IF;
RETURN s;
END;
/
SELECT name, ssn, fnGender(ssn) FROM insa;
-- 생일 구하기
CRTEATE OR REPLACE FUNCTION fnBirth
(
ssn IN VARCHAR2
)
RETURN DATE
IS
BEGIN
IF LENGTH(ssn) != 14 THEN
RAISE_APPLICATION_ERROR(-20001, '주민번호는 14자리');
END IF;
RETURN TO_DATE(SUBSTR(ssn, 1, 6), 'RRMMDD');
END;
/
SELECT name, ssn, fnGender(ssn), fnBirth(ssn) FROM insa;
-- 나이 구하기
CRTEATE OR REPLACE FUNCTION fnAge
(
ssn IN VARCHAR2
)
RETURN NUMBER
IS
age NUMBER;
s DATE;
BEGIN
s := fnBirth(ssn);
age := TRUNC(MONTHs_BETWEEN(SYSDATE, s)/12);
RETURN age;
END;
/
SELECT name, ssn, fnGender(ssn), fnBirth(ssn), fnAge(ssn) FROM insa;
-- fnPow(2, 10), fnPow(2, -2)
CRTEATE OR REPLACE FUNCTION fnPow
(
a NUMBER,
b NUMBER
)
RETURN NUMBER
IS
s NUMBER := 1;
BEGIN
IF b > 0 THEN
FOR n IN 1..b LOOP
s := s * a;
END LOOP;
ELSE
FOR n IN 1..(-b) LOOP
s := s / a;
END LOOP;
END IF;
RETURN s;
END;
/
SELECT fnPow(2, 10), fnPow(2, -2) FROM dual;
//*****************************************
-- 문제
-- score1 테이블 작성
hak 문자(20) 기본키
name 문자(30) NOT NULL
kor 숫자(3) NOT NULL
eng 숫자(3) NOT NULL
mat 숫자(3) NOT NULL
-- score2 테이블 작성
hak 문자(20) 기본키, score1 테이블의 참조키
kor 숫자(2,1) NOT NULL
eng 숫자(2,1) NOT NULL
mat 숫자(2,1) NOT NULL
CREATE TABLE score1 (
hak VARCHAR2(20) NOT NULL
,name VARCHAR2(30) NOT NULL
,kor NUMBER(3) NOT NULL
,eng NUMBER(3) NOT NULL
,mat NUMBER(3) NOT NULL
,CONSTRAINT pk_score1_hak PRIMARY KEY(hak)
);
CREATE TABLE score2 (
hak VARCHAR2(20) NOT NULL
,kor NUMBER(2,1) NOT NULL
,eng NUMBER(2,1) NOT NULL
,mat NUMBER(2,1) NOT NULL
,CONSTRAINT pk_score2_id PRIMARY KEY(hak)
,CONSTRAINT fk_score2_id FOREIGN KEY(hak)
REFERENCES score1(hak)
);
-- 평점을 구하는 함수 작성
-- 함수명 : fnGrade(s)
95~100:4.5 90~94:4.0
85~89:3.5 80~84:3.0
75~79:2.5 70~74:2.0
65~69:1.5 60~64:1.0
60미만 0
CREATE OR REPLACE FUNCTION fnGrade
(
pScore NUMBER
)
RETURN NUMBER
IS
n NUMBER(2,1);
BEGIN
IF pScore>=95 THEN n:=4.5;
ELSIF pScore>=90 THEN n:=4.0;
ELSIF pScore>=85 THEN n:=3.5;
ELSIF pScore>=80 THEN n:=3.0;
ELSIF pScore>=75 THEN n:=2.5;
ELSIF pScore>=70 THEN n:=2.0;
ELSIF pScore>=65 THEN n:=1.5;
ELSIF pScore>=60 THEN n:=1.0;
ELSE n:=0.0;
END IF;
RETURN n;
END;
/
SELECT fnGrade(85), fnGrade(90) FROM DUAL;
-- score1 테이블과 score2 테이블에 데이터를 추가하는 프로시져 만들기
프로시져명 : pScoreInsert
실행예 : EXEC pScoreInsert('1111', '가가가', 80, 60, 75);
score1 테이블 => '1111', '가가가', 80, 60, 75 정보 추가
score2 테이블 => '1111', 3.0, 1.0, 2.5 정보 추가(국, 영, 수 점수가 평점으로 계산되어 추가)
단, 국여, 영어, 수학 점수는 0~100 사이가 아니면 예외 발생하고 종료
CREATE OR REPLACE PROCEDURE pScoreInsert
(
phak IN VARCHAR2
,pname IN VARCHAR2
,pkor IN NUMBER
,peng IN NUMBER
,pmat IN NUMBER
)
IS
BEGIN
IF pkor<0 OR pkor>100 OR peng<0 OR peng>100 OR pmat<0 OR pmat>100 THEN
RAISE_APPLICATION_ERROR(-20001, '점수는 0~100사이만 가능합니다.');
END IF;
INSERT INTO score1(hak, name, kor, eng, mat) VALUES
(phak, pname, pkor, peng, pmat);
INSERT INTO score2(hak, kor, eng, mat) VALUES
(phak, fnGrade(pkor), fnGrade(peng), fnGrade(pmat));
COMMIT;
END;
/
EXEC pScoreInsert('111', '가가가', 80, 75, 95);
EXEC pScoreInsert('222', '나나나', 70, 65, 50);
EXEC pScoreInsert('333', '다다다', 180, 90, 85);
SELECT * FROM score1;
SELECT * FROM score2;
-- score1 테이블과 score2 테이블에 데이터를 수정하는 프로시져 만들기
프로시져명 : pScoreUpdate
실행예 : EXEC pScoreUpdate('1111', '가가가', 90, 60, 75);
score1 테이블 => 학번이 '1111' 인 자료를 '가가가', 90, 60, 75 으로 정보 수정
score2 테이블 => 학번이 '1111' 인 자료를 4.0, 1.0, 2.5 으로 정보 수정(국, 영, 수 점수가 평점으로 계산되어 수정)
단, 국여, 영어, 수학 점수는 0~100 사이가 아니면 예외 발생하고 종료
CREATE OR REPLACE PROCEDURE pScoreUpdate
(
phak IN VARCHAR2
,pname IN VARCHAR2
,pkor IN NUMBER
,peng IN NUMBER
,pmat IN NUMBER
)
IS
BEGIN
IF pkor<0 OR pkor>100 OR peng<0 OR peng>100 OR pmat<0 OR pmat>100 THEN
RAISE_APPLICATION_ERROR(-20001, '점수는 0~100사이만 가능합니다.');
END IF;
UPDATE score1 SET name=pname, kor=pkor, eng=peng, mat=pmat WHERE hak=phak;
UPDATE score2 SET kor=fnGrade(pkor), eng=fnGrade(peng), mat=fnGrade(pmat) WHERE hak=phak;
COMMIT;
END;
/
EXEC pScoreUpdate('111', '가가가', 95, 80, 95);
SELECT * FROM score1;
SELECT * FROM score2;
-- score1 테이블과 score2 테이블에 데이터를 삭제하는 프로시져 만들기
프로시져명 : pScoreDelete
실행예 : EXEC pScoreDelete('1111');
score1 과 score2 테이블 정보 삭제
CREATE OR REPLACE PROCEDURE pScoreDelete
(
phak IN VARCHAR2
)
IS
BEGIN
DELETE FROM score2 WHERE hak=phak;
DELETE FROM score1 WHERE hak=phak;
COMMIT;
END;
/
-- score1과 score2 테이블에 가상 컬럼을 추가하여 총점과 평균계산하기
score1 : tot NUMBER(3), ave NUMBER(4,1)
score2 : tot NUMBER(4, 1), ave NUMBER(4,1)
ALTER TABLE score1 ADD (
tot NUMBER(3) GENERATED ALWAYS AS ( kor+eng+mat ) VIRTUAL
,ave NUMBER(4,1) GENERATED ALWAYS AS ((kor+eng+mat)/3) VIRTUAL
);
ALTER TABLE score2 ADD (
tot NUMBER(4,1) GENERATED ALWAYS AS ( kor+eng+mat ) VIRTUAL
,ave NUMBER(2,1) GENERATED ALWAYS AS ((kor+eng+mat)/3) VIRTUAL
);
SELECT * FROM score1;
SELECT * FROM score2;
'ORACLE(오라클) > ORACLE(오라클) 실습' 카테고리의 다른 글
[오라클 트리거] ORACLE Trigger (0) | 2019.01.16 |
---|---|
[오라클 프로시져(Stored Procedure)] (0) | 2019.01.10 |
[오라클 트랜잭션] oracle transaction (0) | 2019.01.10 |
[ORACLE INLINE VIEW, subquery ] 오라클 인라인뷰, 서브쿼리 (0) | 2019.01.09 |
[ORACLE JOIN]오라클 조인 개념 및 실습. (0) | 2019.01.09 |