일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- framework
- web
- javascript
- mybatis
- javaprogramming
- 오라클
- SpringMVC
- js
- tdd
- CSS
- TIL
- progressive web app
- HTML
- Oracle
- 프레임워크
- JavaScript 내장객체
- 자바스크립트
- 메이븐
- 서브쿼리
- sql
- 생활코딩
- sqldeveloper
- 프로그레시브웹앱
- maven
- 국비지원
- springaop
- TodayILearned
- PWA
- 자바프로그래밍
- 스프링
- Today
- Total
1cm
자바 프로그래밍_Day_41_PL/SQL(2), PROCEDURE, FUNCTION 본문
자바 프로그래밍_Day_41_PL/SQL(2), PROCEDURE, FUNCTION
dev_1cm 2021. 10. 24. 17:11
2021. 10. 15
> PL/SQL 반복문
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
|
/*
2-2) 반복문
1) BASIC LOOP
[표현법]
LOOP
반복적으로 실행시킬 구문
[반복문을 빠져나갈 조건문 작성]
1) IF 조건식 THEN EXIT; END IF;
2) EXIT WHEN 조건식;
END LOOP;
*/
-- 1 ~ 5까지 순차적으로 1씩 증가하는 값을 출력
DECLARE
NUM NUMBER := 1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(NUM);
NUM := NUM + 1;
-- IF NUM > 5 THEN
-- EXIT;
-- END IF;
EXIT WHEN NUM > 5;
END LOOP;
END;
/
|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/*
2) WHILE LOOP
[표현법]
WHILE 조건식
LOOP
반복적으로 실행할 구문;
END LOOP;
*/
-- 1 ~ 5까지 순차적으로 1씩 증가하는 값을 출력
DECLARE
NUM NUMBER := 1;
BEGIN
WHILE (NUM < 5)
LOOP
DBMS_OUTPUT.PUT_LINE(NUM);
NUM := NUM + 1;
END LOOP;
END;
/
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
-- 구구단(2 ~ 9단) 출력
DECLARE
DAN NUMBER := 2;
SU NUMBER;
BEGIN
WHILE DAN <= 9
LOOP
SU := 1;
WHILE SU <= 9
LOOP
DBMS_OUTPUT.PUT_LINE(DAN || ' X ' || SU || ' = ' || DAN * SU);
SU := SU + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
DAN := DAN + 1;
END LOOP;
END;
/
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/*
3) FOR LOOP
[표현법]
FOR 변수 IN [REVERSE] 초기값,.. 최종값
LOOP
반복적으로 실행할 구문;
END LOOP;
*/
-- 1 ~ 5까지 순차적으로 1씩 증가하는 값을 출력
BEGIN
FOR NUM IN 1..5
LOOP
DBMS_OUTPUT.PUT_LINE(NUM);
END LOOP;
END;
|
cs |
1
2
3
4
5
6
7
8
|
-- 역순으로 출력
BEGIN
FOR NUM IN REVERSE 1..5
LOOP
DBMS_OUTPUT.PUT_LINE(NUM);
END LOOP;
END;
/
|
cs |
-> 구구단 - 짝수만 출력 - reverse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-- 구구단 (2 ~ 9단) 출력 (단, 짝수단만 출력한다.)
BEGIN
FOR DAN IN REVERSE 2..9
LOOP
IF (MOD(DAN, 2) = 0) THEN
FOR SU IN 1..9
LOOP
DBMS_OUTPUT.PUT_LINE(DAN || ' X '|| SU || ' = ' || DAN * SU);
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END IF;
END LOOP;
END;
/
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
-- 반복문(FOR 구문)을 이용한 데이터 삽입
CREATE TABLE TEST(
NUM NUMBER,
CREATE_DATE DATE
);
SELECT * FROM TEST;
TRUNCATE TABLE TEST;
-- TEST 테이블에 10개의 행을 INSERT하는 PL/SQL 작성
BEGIN
FOR NUM IN 1..10
LOOP
INSERT INTO TEST VALUES(NUM, SYSDATE);
IF (MOD(NUM, 2) != 0) THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END;
/
|
cs |
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
32
|
/*
3) 예외처리부 (EXCEPTION SECTION)
예외란 실행 중 발생하는 오류를 뜻하고 PL/SQL 문에서 발생한 예외를 예외처리부에서 코드적으로 처리가 가능하다.
[표현식]
DECLARE
...
BEGIN
...
EXCEPTION
WHEN 예외명 1 THEN 예외처리구문 1;
WHEN 예외명 2 THEN 예외처리구문 2;
...
WHEN OUTERS THEN 예외처리구문;
* 오라클에서 미리 정의되어 있는 예외(시스템 예외)
- NO_DATE_FOUND : SELECT 문의 수행 결과가 한 행도 없을 경우 발생한다.
- TOO_MANY_ROWS : 한 행이 리턴되어야 하는데 SELECT 문에서 여러 개의 행을 반환할 때 발생한다.
- ZERO_DIVIDE : 숫자를 0으로 나눌 때 발생한다.
- DUP_VAL_ON_INDEX : UNIQUE 제약 조건을 가진 컬럼에 중복된 데이터가 INSERT 될 때 발생한다.
*/
-- 사용자가 입력한 수로 나눗셈 연산
DECLARE
RESULT NUMBER;
BEGIN
RESLUT := 10 / &숫자;
DBMS_OUTPUT.PUT_LINE('결과 :' || RESULT);
EXCEPTION
WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT_LINE('나누기 연산시 0으로 나눌 수 없습니다.');
END;
/
|
cs |
1
2
3
4
5
6
7
8
9
10
|
-- UNIQUE 제약조건 위배시
BEGIN
UPDATE EMPLOYEE
SET EMP_ID = 200
WHERE EMP_NAME = '&이름';
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('이미 존재하는 사번입니다.');
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('오류가 발생했습니다.');
END;
/
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
-- 너무 많은 행이 조회가 되었을 때
DECLARE
EID EMPLOYEE.EMP_ID%TYPE;
ENAME EMPLOYEE.EMP_NAME%TYPE;
BEGIN
SELECT EMP_ID, EMP_NAME
INTO EID, ENAME
FROM EMPLOYEE
WHERE MANAGER_ID = '&사수번호';
DBMS_OUTPUT.PUT_LINE('사번 : ' || EID);
DBMS_OUTPUT.PUT_LINE('사원명 : ' || ENAME);
EXCEPTION
-- WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('너무 많은 행이 조회되었습니다.');
-- WHEN TNO_DATE_FOUND THEN DBMS_OUTPUT.PUT_LINE('조회 결과가 없습니다.');
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('오류가 발생했습니다.');
END;
/
|
cs |
> PROCEDURE
-> PL/SQL문을 저장하는 객체로 필요할 때마다 복잡한 구문을 다시 입력할 필요 없이 간단하게 호출해서 실행 결과를 얻을 수 있음
-> 작성하고 나서 바로 결과값을 반환하지 않고, 실행 구문을 호출하여 실행한다.(EXEC)
-> 매개변수 있는 프로시저
-> 프로시저를 정의할 때, CREATE, IS 사이에 프로시저가 전달받을 매개변수 선언이 가능하다.
-> IN/OUT 매개변수 있는 프로시저
-> 매개변수를 선언할 때 IN / OUT으로 구분 -> 매개변수 타입 지정
-> IN : 프로시저 내부에서 사용할 변수
-> OUT : 매개변수를 통해 프로시저 외부에 전달 가능
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
|
/*
<PROCEDURE>
PL/SQL문을 저장하는 객체
필요할 때마다 복잡한 구문을 다시 입력할 필요 없이 간단하게 호출해서 실행 결과를 얻을 수 있다.
특정 로직을 처리하기만 하고 결과값을 반환하지 않는다.
[표현법]
CREATE OR REPLACE PROCEDURE 프로시저명
(
매개변수명 1 [IN|OUT] 데이터타입 [:= DEFAULT 값],
매개변수명 2 [IN|OUT] 데이터타입 [:= DEFAULT 값],
...
)
IS [AS]
선언부
BEGIN
실행부
EXCEPTION
예외처리부
END [프로시저명];
/
[실행방법]
EXECUTE(EXEC) 프로시저명[(매개값1, 매개값2, ...)];
*/
-- 테스트용 테이블 생성
CREATE TABLE EMP_DUP
AS SELECT * FROM EMPLOYEE;
SELECT * FROM EMP_DUP;
|
cs |
1
2
3
4
5
6
7
8
9
10
|
-- 테스트 테이블의 데이터를 모두 삭제하는 프로시저 생성
CREATE OR REPLACE PROCEDURE DEL_ALL_EMP
IS
BEGIN
DELETE FROM EMP_DUP;
COMMIT;
END;
/
|
cs |
-> 데이터가 삭제된 것을 확인할 수 있다.
-> 프로시저도 객체이기 때문에 DROP 구문을 통해 삭제가 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/*
1) 매개변수가 있는 프로시저
프로시저 실행 시 매개변수로 인자값을 전달해야 한다.
*/
CREATE OR REPLACE PROCEDURE DEL_EMP_ID
(
P_EMP_ID EMPLOYEE.EMP_ID%TYPE
)
IS
BEGIN
DELETE FROM EMPLOYEE
WHERE EMP_ID = P_EMP_ID;
END;
/
SELECT * FROM EMPLOYEE;
|
cs |
-> 사번 204 삭제.
-> 202번 사번 입력
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
32
33
34
35
36
37
38
39
40
|
/*
2) IN/OUT 매개변수가 있는 프로시저
IN 매개변수 : 프로시저 내부에서 사용될 변수
OUT 매개변수 : 프로시저 호출부(외부)에서 사용될 값을 담아줄 변수
*/
CREATE OR REPLACE PROCEDURE SELECT_EMP_ID
(
V_EMP_ID IN EMPLOYEE.EMP_ID%TYPE,
V_EMP_NAME OUT EMPLOYEE.EMP_NAME%TYPE,
V_SALARY OUT EMPLOYEE.SALARY%TYPE,
V_BONUS OUT EMPLOYEE.BONUS%TYPE
)
IS
BEGIN
SELECT EMP_NAME, SALARY, NVL(BONUS, 0)
INTO V_EMP_NAME, V_SALARY, V_BONUS
FROM EMPLOYEE
WHERE EMP_ID = V_EMP_ID;
END;
/
-- 바인드 변수(VARIABLE, VAR)
VAR VAR_EMP_NAME VARCHAR2(30);
VAR VAR_SALARY NUMBER;
VAR VAR_BONUS NUMBER;
-- 바인드 변수는 ':변수명' 형태로 참조 가능
EXEC SELECT_EMP_ID('200', :VAR_EMP_NAME, :VAR_SALARY, :VAR_BONUS)
-- 프로시저 밖에서 찍어본다.
PRINT VAR_EMP_NAME;
PRINT VAR_SALARY;
PRINT VAL_BONUS;
-- 바인드 변수 참조 형태 없이도 가능한 구문
SET AUTOPRINT ON;
EXEC SELECT_EMP_ID('201', :VAR_EMP_NAME, :VAR_SALARY, :VAL_BONUS);
EXEC SELECT_EMP_ID('&사번', :VAR_EMP_NAME, :VAR_SALARY, :VAL_BONUS);
|
cs |
-> 바인드 변수 -> :변수명 형태로 참조하여 조회 가능
> FUNCTION
-> 프로시저와 거의 유사한 용도로 사용하지만 실행결과를 되돌려 받을 수 있다는 점에서 프로시저와 다름
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/*
<FUNCTION>
프로시저와 사용 용도가 거의 비슷하지만
프로시저와 다르게 OUT 변수를 사용하지 않아도 실행 결과를 되돌려 받을 수 있다. (RETURN)
[표현법]
CREATE OR REPLACE FUNCTION 함수명
(
매개변수 1 타입,
매개변수 2 타입,
...
)
RETURN 데이터타입
IS
선언부
BEGIN
실행부
RETURN 반환값; -- 프로시저와 다르게 RETURN 구문이 추가된다.
EXCEPTION
예외처리부
END [함수명];
/
*/
-- 사번을 입력받아 해당 사원의 보너스를 포함하는 연봉을 계산하고 리턴하는 함수 생성
CREATE OR REPLACE FUNCTION BONUS_CALC
(
V_EMP_ID EMPLOYEE.EMP_ID%TYPE
)
RETURN NUMBER
IS
V_SAL EMPLOYEE.SALARY%TYPE;
V_BONUS EMPLOYEE.BONUS%TYPE;
BEGIN
SELECT SALARY, NVL(BONUS, 0)
INTO V_SAL, V_BONUS
FROM EMPLOYEE
WHERE EMP_ID = V_EMP_ID;
RETURN (V_SAL + (V_SAL * V_BONUS)) * 12;
END;
/
-- FUNCTION 확인 가능
SELECT * FROM USER_SOURCE;
-- 함수 결과를 반환받아 저장할 바인드 변수 선언
VAR VAR_CALC_SALARY NUMBER;
-- 함수 호출
-- EXEC BONUS_CALC('&사번'); -- 반환하는 값이 있기 때문에 반환값을 받아줘야 한다.
EXEC :VAR_CALC_SALARY := BONUS_CALC('&사번');
PRINT VAR_CALC_SALARY;
-- 함수를 SELECT 문에서 사용하기 (함수는 RETURN 값이 있어서 SELECT 문에서 사용가능 (EXEC 생략 가능))
SELECT EMP_ID, EMP_NAME, SALARY, BONUS, BONUS_CALC(EMP_ID) AS "연봉"
FROM EMPLOYEE
WHERE BONUS_CALC(EMP_ID) > 40000000
-- ORDER BY "연봉";
ORDER BY BONUS_CALC(EMP_ID) DESC;
|
cs |
'국비지원_Java > Java Programming_1' 카테고리의 다른 글
자바 프로그래밍_Day_43_문제풀이 (0) | 2021.10.26 |
---|---|
자바 프로그래밍_Day_42_CURSOR, TRIGGER (0) | 2021.10.26 |
자바 프로그래밍_Day_40_QL/SQL (0) | 2021.10.24 |
자바 프로그래밍_Day_39_DML, VIEW, SEQUENCE, INDEX (0) | 2021.10.23 |
자바 프로그래밍_Day_38_DML(DELETE), TCL, VIEW (0) | 2021.10.19 |