CS/데이타베이스

[실습] Stored Procedure (저장 프로시저)

코딩하는 포메라니안 2021. 11. 11. 22:29

1. Stored Procedure란?

- 쿼리문의 집합으로 어떤 동작을 일괄 처리하기 위한 용도로 사용

- 함수와 유사한 역할

- 모듈화시켜서 호출만 해서 실행 가능

 

 

 

2. 실습

1. procedure 생성 및 호출

use academicDB;

drop procedure IF EXISTS studentProc;
DELIMITER $$
 create procedure studentProc()
 BEGIN
 select * from student; 
 END $$
DELIMITER ;

call studentProc();/*호출*/

 

+) 참고 : procedure의 더 많은 사용법으로 궁금하지 않으면, 바로 다음 단계로 가도 된다.

1) 입력 매개변수 2개인 경우

drop procedure IF EXISTS studentProc2;
DELIMITER $$
 create procedure studentProc2
 (IN userName varchar(10), IN deptName varchar(20) )
 BEGIN
 select * from student where 
 sname = userName and sdept = deptName; 
 END $$
DELIMITER ;
call studentProc2('김철수', '컴퓨터');

 

2) 출력 매개변수 지정하기

drop procedure IF EXISTS testProc;
DELIMITER $$
 create procedure testProc(IN txtValue varchar(10), OUT outValue int )
 BEGIN
 insert into testTBL values(null, txtValue);
 select max(id) into outValue from testTBL; 
 END $$
DELIMITER ;
create table IF NOT EXISTS testTBL (
 id int auto_increment primary key,
 txt char(10)
);

call testProc('테스트값', @myValue);
select concat('현재 입력된 ID 값 ==>', @myValue);

 

3) 조건문 사용

drop procedure IF EXISTS ifelseProc;
DELIMITER $$
 create procedure ifelseProc(IN number int )
 BEGIN
 DECLARE eScore int;
 select score into eScore from enroll where sno = number;
 IF (eScore >= 90) THEN select 'A 학점';
 ELSE select 'B 학점';
 END IF;
 END $$
DELIMITER ;
call ifelseProc (20183654);

 

4) 커서 사용 = 다수의 행 질의 후 한 행씩 처리

drop procedure IF EXISTS cursorProc;
DELIMITER $$
 create procedure cursorProc()
 BEGIN
 DECLARE eScore int; -- score 변수
 DECLARE count int DEFAULT 0; -- 읽은 행 수
 DECLARE total int DEFAULT 0; -- 합계 
 DECLARE endOfRow boolean default FALSE; -- 행의 끝 여부
 DECLARE cur CURSOR FOR select score from enroll; -- 커서 선언
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET 
 endOfRow = TRUE; -- 행의 끝이면 endOfRow 변수에 TRUE를 대입
 OPEN cur; -- 커서 열기
 cursor_loop: LOOP
 FETCH cur INTO eScore;
 IF endOfRow THEN 
 LEAVE cursor_loop; -- 행의 끝이면 loop 종료
 END IF;
 SET count = count + 1;
 SET total = total + eScore;
 END LOOP cursor_loop; 
 select concat('수강생 평균 점수 ==> ', (total/count));
 CLOSE cur; -- 커서 닫기
 END $$
DELIMITER ;
CALL cursorProc();
/*학생별 평균 점수가 95점 이상이면 "전액장학금", 90점 이상이면 "반액 장학금"을 입력*/
use academicdb;
alter table student add scholarship varchar(20); /*테이블에 장학금열 추가*/

drop procedure IF EXISTS scholarProc;
DELIMITER $$
    create procedure scholarProc()
    BEGIN
    DECLARE number int;
    DECLARE avgScore double;
    DECLARE scholar varchar(20);
    
    DECLARE endOfRow boolean default FALSE;
    DECLARE cur CURSOR FOR select S.sno, avg(score) from enroll E inner join student S on E.sno = S.sno group by E.sno;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET endOfRow = TRUE;
    OPEN cur;
    cursor_loop: LOOP
    FETCH cur INTO number, avgScore;
    IF endOfRow THEN 
    LEAVE cursor_loop;
    END IF;
    CASE
    when (avgScore >= 95.0) then set scholar = "전액 장학금";
    when (avgScore >= 90.0) then set scholar = "반액 장학금";
    else set scholar = null;
    END CASE;
    update student set scholarship = scholar where sno = number;
    END LOOP cursor_loop; 
    CLOSE cur;
    select * from student;
    END $$
DELIMITER ;

CALL scholarProc();

 

 

2. JDBC에서 사용

- CallableStatement stmt = null;

- stmt = conn.prepareCall("call studentProc()");

- rs = stmt.executeQuery();

위 세 문장만 주의해서 쓰면 된다.

package test;

import java.sql.*;
public class JDBCtest_01 {
	public static void main (String[] args)
	{ 
		 try {
			 Class.forName("com.mysql.cj.jdbc.Driver");
			 System.out.println("OK!");
		 } 
		 catch(ClassNotFoundException ee) {
			 System.exit(0);
		 }
		 Connection conn = null;
		 String url = "jdbc:mysql://localhost/academicDB?serverTimezone=UTC";
		 //academicDB 사용
		 String id = "root"; 
		 String pass = "root";
		 CallableStatement stmt = null;//수정1
		 ResultSet rs = null;
		 try {
			 conn = DriverManager.getConnection(url, id, pass);
			 stmt = conn.prepareCall("call studentProc()");//수정2
			 rs = stmt.executeQuery();//수정3
			 while(rs.next()) {
				 System.out.println(rs.getInt(1)+", "+rs.getString(2)+", "+rs.getString(3)+", "+rs.getString(4));
			 }
			 rs.close();
			 stmt.close();
			 conn.close();
		 } 
		 catch(SQLException ee) {
			 System.err.println("error = " + ee.toString());
		 }
	}
}

 

'CS > 데이타베이스' 카테고리의 다른 글

[실습] 트리거  (0) 2021.12.15
7. SQL  (0) 2021.12.15
[실습] 고급 SQL SELECT문  (0) 2021.11.01
[실습] 키 생성  (0) 2021.10.20
[실습] 인덱스 생성과 삭제  (0) 2021.10.20