[JDBC] Statement, ResultSet, PreparedStatement, CallableStatement

suyeon·2022년 5월 10일
1

JDBC

목록 보기
2/2
post-thumbnail

220510

🎇 Statement 클래스

  • Connection
    - DB 연결 / 종료
  • Statment
    • SQL 실행하는 역할
    • SQL Developer에서 SQL 작성 + 블럭 + Ctrl/Enter
    • Connection 클래스를 통해서 생성
    • 모든 SQL 실행 가능

[ Statement 종류 ]

  1. 텍스트 쿼리 실행용 ⭐

    1. Statement
      • 기본
    2. PreparedStatement
      • Statement 개량 > 매개 변수 처리 특화
      • 안정성 높음, 가독성 높음
      • 코드량 증가
  2. 프로시저 실행용

    1. CallableStatement
      • Statement 개량 > 프로시저 호출 전용
      • PreparedStatement 유사

[ 메소드 종류 ]

  • 반환값이 없는 쿼리 : select빼고 나머지
    - int 변수명.executeUpdate(sql)
  • 반환값이 있는 쿼리 : select
    - ResultSet 변수명.executeQuery(sql);

✔ [ Statement 예제 ]

오라클에 테이블 만들어 놓음

-- 주소록 테이블
select * from tblAddress;

create table tblAddress(
    seq number primary key,                                 -- PK
    name varchar2(10) not null,                             -- 이름
    age number(3) not null check(age between 0 and 150),    -- 나이
    gender char(1) not null check(gender in ('m','f')),     -- 성별(m,f)
    tel varchar2(15) not null,                              -- 전화번호
    address varchar2(300) not null,                         -- 주소
    regdate date default sysdate not null                   -- 등록일
);

create sequence seqAddress;

ex1) INSERT 실행

1. DB 접속
2. SQL 실행
3. DB 종료
try {

		Connection conn = null; -- DB 연결
		Statement stat = null; -- SQL 실행

			// 1. DB 접속
			conn = DBUtil.open();

			if (!conn.isClosed()) {

				System.out.println("연결 성공");

				// 2. SQL 실행
				// - 자바는 SQL을 모른다. > SQL을 문자열로 취급한다.(아무 의미없이)
				String sql =
						"insert into tblAddress (seq, name, age, gender, tel, address, regdate) 
                        	values (seqAddress.nextVal, '아무개', 25, 'm', '010-5555-5555','서울시 강남구 대치동 OO빌딩', default)";

				// stat > SQL 실행 > 어느 DB + 어떤 계정으로 SQL 실행할지는 모르고 있음
                // 쿼리 수행할래?
				stat = conn.createStatement();


				// 반환값이 없는 쿼리 > 나머지
				// - (int) stat.executeUpdate(sql);

				// SQL Developer > Ctrl + Enter 동일!
				int result = stat.executeUpdate(sql); // result는 '1 행 이(가) 삽입되었습니다.'

				if (result == 1) {
					System.out.println("등록 성공");
				} else {
					System.out.println("등록 실패");
				}

                stat.close();
				conn.close();
				// 모든 자원은 close! 꼭 닫아야해.
			}

			// 3. DB 종료
			DBUtil.close();

		} catch (Exception e) {
			System.out.println("Ex03_Statement.m1");
			e.printStackTrace();
		}

ex2) UPDATE 실행

		Connection conn = null;
		Statement stat = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			String sql = "update tblAddress set age = age + 1 where seq = 1";

			int result = stat.executeUpdate(sql);

			System.out.println(result);

			stat.close();
			conn.close();


		} catch (Exception e) {
			System.out.println("Ex03_Statement.m2");
			e.printStackTrace();
		}

ex3) CREATE 실행

		Connection conn = null;
		Statement stat = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			String sql = "create table tblAddress2 ("
					+ "    seq number primary key, "
					+ "    name varchar2(10) not null,"
					+ "    age number(3) not null check (age between 0 and 150),"
					+ "    gender char(1) not null check(gender in ('m','f')),"
					+ "    tel varchar2(15) not null,"
					+ "    address varchar2(300) not null, "
					+ "    regdate date default sysdate not null "
					+ ")";
                    
			int result = stat.executeUpdate(sql);

			System.out.println(result);

			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex03_Statement.m3");
			e.printStackTrace();
		}

ex4) 사용자 입력 > INSERT 실행

		// UI + SQL
		// - 사용자 입력 > insert

		Connection conn = null;
		Statement stat = null;

		Scanner scan = new Scanner(System.in);

		try {

			// 자바 자로형 <- 아무 연관성X -> 오라클 자료형
			// - 언어가 다르면 자료형 절대 호환 안된다.
			System.out.print("이름: ");
			String name = scan.nextLine(); // varchar2

			System.out.print("나이: ");
			String age = scan.nextLine(); // number

			System.out.print("성별(m,f): ");
			String gender = scan.nextLine(); // char

			System.out.print("전화번호: ");
			String tel = scan.nextLine(); // varchar2

			System.out.print("주소: ");
			String address = scan.nextLine(); // varchar2

			conn = DBUtil.open();
			stat = conn.createStatement();

			String sql = String.format(
					"insert into tblAddress (seq, name, age, gender, tel, address, regdate) 
                    	values (seqAddress.nextVal, '%s', %s, '%s', '%s', '%s', default)", 
                        								name, age, gender, tel, address);

			int result = stat.executeUpdate(sql);

			System.out.println(result);

			stat.close();
			conn.close();
            
		} catch (Exception e) {
			System.out.println("Ex03_Statement.m4");
			e.printStackTrace();
		}

🎇 ResultSet 클래스

  • 결과값을 저장할 수 있다.
  • 저장된 값을 한 행 단위로 불러올 수 있다.
  • 한 행에서 값을 가져올 때는 자료형을 지정해 불러올 수 있다.

[ 메소드 종류 ]

  • 반환값이 있는 쿼리 > select
    - ResultSet stat.executeQuery(sql);
  • 다음행이 있을 경우 true, 없을 경우 flase
    - next()
  • 커서가 가르키고 있는 레코드의 특정 컬럼값(정수)을 가져온다.
    - getInt(int index)
  • 커서가 가르키고 있는 레코드의 특정 컬럼값(문자열)을 가져온다.
    - getString(int index),
    - getString(String label)

✔ [ ResultSet 예제 ]

  • 레코드가 1개라고 확실할 때 if문 사용한다.

ex1) 단일값 반환 - 1행 1열

		Connection conn = null;
		Statement stat = null;
        
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			String sql = "select count(*) as cnt from tblInsa";

			// 반환값 X -> executeUpdate(); -> 실행은 되지만 올바른 결과를 얻을 수가 없다.
			// 반환값 O -> executeQuery();

			// ResultSet == 커서(Cursor) > 커서가 가리키고 있는 레코드의 특정 컬럼값을 가져온다.
            // 조회한 결과들을 ResultSet에 rs에 저장
			rs = stat.executeQuery(sql);

			rs.next(); // 커서를 1줄 전진 > 레코드 위치

			// rs.getXXX(); (XXX-> 자료형) 현재 커서가 가르키고 있는 레코드의 특정 컬럼값을 가져와라
			int cnt1 = rs.getInt(1); // 컬럼 순서(Index)
			int cnt2 = rs.getInt("cnt"); // 컬럼명 ******** 주의!! as 꼭 붙여라
			String cnt3 = rs.getString("cnt");

			System.out.println(cnt1);
			System.out.println(cnt2);
			System.out.println(cnt3);

			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex04_select.m1");
			e.printStackTrace();
		}

ex2) 다중값 반환 - 1행 N열 (레코드 1줄 + 여러개 컬럼)

		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			String sql = "select name, age, tel, address from tblAddress where seq = 5";

			rs = stat.executeQuery(sql);

			// rs.next()를 통해 다음행을 내려갈 수 있으면 true를 반환하고, 커서를 한칸 내림
            // 다음행이 없으면 false를 반환 
			if (rs.next()) {
            
				System.out.println("이름: " + rs.getString("name"));
				System.out.println("나이: " + rs.getString("age"));
				System.out.println("전화번호: " + rs.getString("tel"));
				System.out.println("주소: " + rs.getString("address"));
                
			} else {
				System.out.println("데이터가 없습니다.");
			}

			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex04_select.m2");
			e.printStackTrace();
		}

ex3) 다중값 반환 - N행 1열 (레코드 N줄 + 컬럼 1개)

		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();


			String sql = "select name from tblInsa order by name";

			// rs가 가리키고 있는거!
			// 60명
			rs = stat.executeQuery(sql);

			rs.next();
			rs.next();
			rs.next();

			// 몇바퀴? > 57바퀴
			while (rs.next()) {
				System.out.println("이름: " + rs.getString("name"));
			}

			// System.out.println("이름: " + rs.getString("name")); -> 출력문 : 결과 집합을 모두 소모했음

			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex04_select.m3");
			e.printStackTrace();
		}

ex4) 다중값 반환 - N행 N열 (레코드 N줄 + 컬럼 N개)

		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			String buseo = "총무부";

			String sql =
					"select name, jikwi, city, basicpay from tblInsa where buseo = '" + buseo + "'";

			rs = stat.executeQuery(sql);

			System.out.println("[이름]\t[직위]\t[지역]\t[급여]");
			while (rs.next()) {
				// 직원1명
				System.out.printf("%s\t%s\t%s\t%,10d원\n", rs.getString("name"),
						rs.getString("jikwi"), rs.getString("city"), rs.getInt("basicpay"));
			}

			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex04_select.m4");
			e.printStackTrace();
		}

ex5) 연습문제

		// tblInsa + tblBonus
		// 요구사항] 특정 직원에게 보너스를 지급하세요.
		// 1. 모든 직원 명단을 출력(직원번호, 이름, 부서, 직위) > m4() 참조
		// 2. 사용자 > 직원 선택(직원번호 입력)
		// 3. 사용자 > 보너스 급액 입력
		// 4. 보너스 지급 > insert tblBonus
		// 5. 지급된 내역을 명단 출력(직원번호, 이름, 부서, 직위, 보너스 금액) > m4() 참조


		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		try {
        
			conn = DBUtil.open();
			stat = conn.createStatement();

			// 1.
			System.out.println("         [직원명단]");
			String sql = "select num, name, buseo, jikwi from tblInsa";
			rs = stat.executeQuery(sql);

			while (rs.next()) {
				System.out.printf("%s, %s, %s, %s\n", rs.getString("num"), rs.getString("name"),
						rs.getString("buseo"), rs.getString("jikwi"));
			}
			rs.close();

			// 2.
			System.out.print("보너스를 지급할 직원 번호를 선택하세요 : ");
			Scanner scan = new Scanner(System.in);
			String num = scan.nextLine();

			// 3.
			System.out.print("보너스를 지급할 금액을 입력하세요 : ");
			String money = scan.nextLine();


			// 4.
			sql = String.format(
					"insert into tblBonus (seq, num, bonus) 
                    	values(seqBonus.nextVal, %s, %s)", num, money);

			int result = stat.executeUpdate(sql);

			// 5.
			if (result > 0) {
				
				System.out.println("보너스 지급을 완료했습니다.");
				System.out.println();

				System.out.println("[번호]\t[이름]\t[부서]\t[직위]\t[보너스]");

				sql = "select a.num as anum, a.name as aname, a.buseo as abuseo, a.jikwi as ajikwi, b.bonus as bbonus from tblInsa a inner join tblBonus b on a.num = b.num";

				rs = stat.executeQuery(sql);
				
				while (rs.next()) {
					// as 붙여라!!!!!!
					System.out.printf("%s\t%s\t%s\t%s\t%,10d원\n", 
							rs.getString("anum"),
							rs.getString("aname"),
							rs.getString("abuseo"),
							rs.getString("ajikwi"),
							rs.getInt("bbonus"));
				}
				
				System.out.println();
				System.out.println("프로그램 종료");
				
			}else {
				System.out.println("보너스 지급을 실패했습니다.");
			}
			
			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex04_select.m5");
			e.printStackTrace();
		}

ex6) sql 주의점 - AS

		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			// 회원명 + 대여한 비디오명
			String sql =
					"select m.name as mname, v.name as vname 
                    	from tblVideo v 
                        inner join tblRent r 
                        on v.seq = r.video 
                        inner join tblMember m 
                        on m.seq = r.member";

			rs = stat.executeQuery(sql);

			while (rs.next()) {

				// 값 나옴
				// System.out.println(rs.getString(1));
				// System.out.println(rs.getString(2));

				// 값 안 나옴
				// System.out.println(rs.getString("m.name"));
				// System.out.println(rs.getString("v.name"));

				// System.out.println(rs.getString("name"));
				// System.out.println(rs.getString("name_1")); -> X

				// System.out.println(rs.getString("name")); m.name -> 김유신
				// System.out.println(rs.getString("name")); m.name -> 김유신

				// AS 꼭 붙여주자!
				System.out.println(rs.getString("mname"));
				System.out.println(rs.getString("vname"));

			}

			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

ex7) 요구사항] 영업부 직원수와 영업부 직원 명단을 출력하시오.
1. select count() as cnt from tblInsa where buseo = '영업부'
2. select
from tblInsa where buseo = '영업부'

		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			stat = conn.createStatement();

			String sql = "";
			
            // 1번 요구사항
			sql = "select count(*) as cnt from tblInsa where buseo = '영업부'";
			rs = stat.executeQuery(sql);

			// 레코드가 1개라고 확실할때 if문으로
			if (rs.next()) {
				System.out.println("직원수 : " + rs.getString("cnt"));
			}
			rs.close();


			// 2번 요구사항 + 1번 요구사항도 가능
			sql = "select * from tblInsa where buseo = '영업부'";
			rs = stat.executeQuery(sql);

			int n = 0;
			// 레코드가 여러개라고 while문
			while (rs.next()) {
				System.out.println(rs.getString("name"));
				n++; // 1번 요구사항
			}
            
			System.out.println("직원수: " + n);
            
            // 자원 해제 코드, Clean-up code > 꼭 안 닫아도 자동으로 닫아주지만, 직접 해주는게 좋다.
			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			System.out.println("Ex04_select.m8");
			e.printStackTrace();
		}

🎇 PreparedStatement 클래스

Statement vs PreparedStatement

  • Statement
    - 정적 쿼리 (매개 변수가 없는 쿼리)
    - 고정값, 변화가 없는 값에 사용
    • 똑같은 일을 하는 쿼리
  • PreparedStatement
    - 동적 쿼리 (매개 변수가 있는 쿼리)
    - 사용자 입력값에 사용
    • 나중에 결정하거나, 실행할때 마다 값이 바뀌는 쿼리
      - ? : 오라클 매개변수
      - SQL 작성이 용이함
      - 매개변수값으로 부적절한 값이 있어도 자동으로 이스케이프(escape)를 시켜줌 ★★★

✔ [ PreparedStatement 예제 ]

		// insert > 사용자 입력
		String name = "하하하";
		String age = "20";
		String gender = "m";
		String tel = "010-1211-1111";
		String address = "서울시 동대문구 이문's동";

		// address = address.replace("'", "''");

		Connection conn = null;
		Statement stat = null;
		PreparedStatement pstat = null;

		try {

			conn = DBUtil.open();

			// Statement
			String sql = String.format(
					"insert into tblAddress (seq, name, age, gender, tel, address, regdate) 
                    	values (seqAddress.nextVal, '%s', %s, '%s', '%s', '%s', default)",
													name, age, gender, tel, address);

			stat = conn.createStatement(); // A.

			System.out.println(sql);

			int result = stat.executeUpdate(sql); // A. 실행 시 SQL 대입
			System.out.println(result);


			// PreparedStatement
            // ? : 오라클 매개변수
			sql = String.format(
					"insert into tblAddress (seq, name, age, gender, tel, address, regdate) 
                    	values (seqAddress.nextVal, ?, ?, ?, ?, ?, default)",
										name, age, gender, tel, address);

			pstat = conn.prepareStatement(sql); // B. 미리 SQL 대입
			
            // 인자값에 대한 처리 추가 진행(***)
			pstat.setString(1, name); // 1번째 물음표에 name을 넣어라.
			pstat.setString(2, age);
			pstat.setString(3, gender);
			pstat.setString(4, tel);
			pstat.setString(5, address);

			int result = pstat.executeUpdate(); // B.
			System.out.println(result);

		} catch (Exception e) {
			System.out.println("Ex05_PreparedStatement.m1");
			e.printStackTrace();
		}
		Connection conn = null;
		Statement stat = null;
		PreparedStatement pstat = null;
		ResultSet rs = null;

		try {
        
			conn = DBUtil.open();
			
            // 정적 쿼리
			String sql = "select name from tblInsa where num = 1001";

			stat = conn.createStatement();
			rs = stat.executeQuery(sql);

			if (rs.next()) {
				System.out.println(rs.getString("name"));
			}

			rs.close();
			stat.close();


			// 동적 쿼리 
			sql = "select name from tblInsa where num = ?";

			pstat = conn.prepareStatement(sql);

			// java.sql.SQLException: 인덱스에서 누락된 IN 또는 OUT 매개변수:: 1
			pstat.setString(1, "1001");
			// pstat.setInt(1, 1001);

			rs = pstat.executeQuery();

			if (rs.next()) {
				System.out.println(rs.getString("name"));
			}

			rs.close();
			pstat.close();
			
			
			
			// 인자없는 쿼리 > pstat
			// ? 전달하는 과정 생략하면 됨.
			sql = "select count(*) as cnt from tblInsa";
			
			pstat = conn.prepareStatement(sql);
			
			rs = pstat.executeQuery();
			
			if(rs.next()) {
				System.out.println(rs.getString("cnt"));
			}
			
			rs.close();
			pstat.close();
			conn.close();
			
		} catch (Exception e) {
			System.out.println("Ex05_PreparedStatement.m2");
			e.printStackTrace();
		}

🎇 CallableStatement 클래스

SQL문을 사용하여 저장 프로시저를 호출할 수 있도록 한다.

  • JDBC는 기본적으로 모든 SQL의 실행은 자동 커밋이 수반된다. > executeXXX() 호출때마다

✔ [ CallableStatement 예제 ]

ex1) 인자값(X), 반환값(X)

  • 프로시저
create or replace procedure procM1
is
begin
    insert into tblAddress (seq, name, age, gender, tel, address, regdate) 
        values (seqAddress.nextVal, '홍길동', 20, 'm', '010-1234-6789', '서울시 강남구 역삼동 한독빌딩', default);
end;
  • Java
		Connection conn = null;
        ResultSet rs = null;
        
		CallableStatement stat = null;
		
		try {

			conn = DBUtil.open();

			// 프로시저 호출구문
			String sql = "{ call procM1 }";

			stat = conn.prepareCall(sql); // 매개변수 처리 능력 보유 > ? 지원

			int result = stat.executeUpdate();

			System.out.println(result);

			stat.close();
			conn.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
Java 컴파일 시 정상 작동시 result 콘솔에 1이 출력된다. Oracle DB 확인 결과 insert 된 결과를 볼 수 있다.

ex2) 인자값(O), 반환값(X)

  • 프로시저
create or replace procedure procM2(
    pname    tblAddress.name%type,
    page     tblAddress.age%type,
    pgender  tblAddress.gender%type,
    ptel     tblAddress.tel%type,
    paddress tblAddress.address%type
)
is
begin
   insert into tblAddress (seq, name, age, gender, tel, address, regdate) 
        values (seqAddress.nextVal, pname, page, pgender, ptel, paddress, default);
end;
/

-- 검증
begin
    procM2('이름',20,'m','010-1234-1234','주소');
end;
/

-- 검증 완료
select * from tblAddress order by seq desc;
  • Java
		Connection conn = null;
		CallableStatement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();

			// begin
			// procM2('이름',20,'m','010-1234-1234','주소');
			// end;
			// String sql = "{ call procM2('상수', 22, 'm', '010-2222-2222','주소') }";
			String sql = "{ call procM2(?, ?, ?, ?, ?) }";

			stat = conn.prepareCall(sql);

			// 인덱스에서 누락된 IN 또는 OUT 매개변수:: 1
			// 인덱스에서 누락된 IN 또는 OUT 매개변수:: 2

			stat.setString(1, "홍길동");
			stat.setString(2, "25");
			stat.setString(3, "m");
			stat.setString(4, "010-3333-3333");
			stat.setString(5, "서울시");

			int result = stat.executeUpdate();

			System.out.println(result);

			stat.close();
			conn.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

ex3) 인자값(X), 반환값(O)

  • 프로시저
create or replace procedure procM3(
   pcount out number
)
is
begin
   select count(*) into pcount from tblAddress;
end procM3;
/

declare
    vcount number;
begin
    procM3(vcount);
    dbms_output.put_line(vcount);
end;
/
  • Java
		Connection conn = null;
		CallableStatement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();
			String sql = "{ call procM3(?) }";

			stat = conn.prepareCall(sql);

			// in 매개변수
			// stat.setString(1,값)

			// out 매개변수
			stat.registerOutParameter(1, OracleTypes.NUMBER);


			// PLSQL 문에서 인출을 수행할 수 없습니다.: next
			// rs = stat.executeQuery();
			// System.out.println(rs.next());

			stat.executeQuery(); // rs(X)

			int count = stat.getInt(1); // Out Parameter 가져오는 역할
			System.out.println(count);

			stat.close();
			conn.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

ex4) 연습문제

  • 프로시저
create or replace procedure procM4(
    pnum    in number,
    pname   out varchar2,
    pbuseo  out varchar2,
    pjikwi  out varchar2,
    pcity   out varchar2
)
is
begin
    select name, buseo, jikwi, city into pname, pbuseo, pjikwi, pcity from tblInsa where num = pnum;
end;
/

declare
    vname tblInsa.name%type;
    vbuseo tblInsa.buseo%type;
    vjikwi tblInsa.jikwi%type;
    vcity tblInsa.city%type;
begin
    procM4(1001,vname,vbuseo,vjikwi,vcity);
    dbms_output.put_line(vname);
    dbms_output.put_line(vbuseo);
    dbms_output.put_line(vjikwi);
    dbms_output.put_line(vcity);
end;
/
  • Java
		// 문제. 직원 번호를 입력하면, 이름, 부서, 직위, 지역을 반환 + 출력
		// procM4
		// - in > 직원 번호
		// - out > 이름
		// - out > 부서
		// - out > 직위
		// - out > 지역


		Connection conn = null;
		CallableStatement stat = null;
		ResultSet rs = null;

		System.out.print("직원번호를 입력하세요: ");
		Scanner scan = new Scanner(System.in);
		String num = scan.nextLine();


		try {

			conn = DBUtil.open();
			String sql = "{ call procM4(?, ?, ?, ?, ?) }";

			stat = conn.prepareCall(sql);

			stat.setString(1, num);
			stat.registerOutParameter(2, OracleTypes.VARCHAR);
			stat.registerOutParameter(3, OracleTypes.VARCHAR);
			stat.registerOutParameter(4, OracleTypes.VARCHAR);
			stat.registerOutParameter(5, OracleTypes.VARCHAR);

			stat.executeQuery();


			System.out.println("이름 : " + stat.getString(2));
			System.out.println("부서 : " + stat.getString(3));
			System.out.println("직위 : " + stat.getString(4));
			System.out.println("지역 : " + stat.getString(5));

			stat.close();
			conn.close();


		} catch (Exception e) {
			e.printStackTrace();
		}

ex5)

  • 프로시저
create or replace procedure procM5(
    pbuseo  in varchar2,
    pcursor  out sys_refcursor
)
is
begin

    open pcursor
    for 
        select name, jikwi, basicpay
            from tblInsa    
                where buseo = pbuseo;

end procM5;
/

declare
    pcursor sys_refcursor;
    vname tblInsa.name%type;
    vjikwi tblInsa.jikwi%type;
    vbasicpay tblInsa.basicpay%type;

begin
    procM5('개발부', pcursor);
    
    loop
        fetch pcursor into vname, vjikwi, vbasicpay;
        exit when pcursor%notfound;
        
        dbms_output.put_line(vname || ', ' || vjikwi || ', ' || vbasicpay);
        
    end loop;
    
end;
/
  • Java
		Connection conn = null;
		CallableStatement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();

			String sql = "{call procM5(?,?)}";

			stat = conn.prepareCall(sql);

			stat.setString(1, "개발부");
			stat.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);

			stat.executeQuery();

			// 오라클 커서 == 자바 ResultSet ********
			rs = (ResultSet) stat.getObject(2);

			while (rs.next()) {
				System.out.println(rs.getString("name"));
				System.out.println(rs.getString("jikwi"));
				System.out.println(rs.getString("basicpay"));
				System.out.println();

			}

			rs.close();
			stat.close();
			conn.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

ex6)

  • 프로시저
create or replace procedure procM6(
    pbuseo in varchar2,
    pcursor out sys_refcursor
)
is

begin
    -- 1. 부서명 > 직원 번호 
    -- 2. 직원번호 > 보너스 지급 내역
    open pcursor for 
        select name, bonus from tblInsa i
            left outer join tblBonus b
                on i.num = b.num
                    where buseo = pbuseo;
end procM6;
/


declare
    vname varchar2(30);
    vbonus number;
    vcursor sys_refcursor;
begin
    procM6('기획부', vcursor);
    
    loop
        fetch vcursor into vname, vbonus;
        exit when vcursor%notfound;
        
        dbms_output.put_line(vname || ' > ' || vbonus);
    end loop;
end;
/
  • Java
		Connection conn = null;
		CallableStatement stat = null;
		ResultSet rs = null;

		try {

			conn = DBUtil.open();

			// 부서명 입력 > 부서의 직원의 보너스 직급 내역 출력
			Scanner scan = new Scanner(System.in);

			System.out.print("부서명: ");
			String buseo = scan.nextLine();

			String sql = "{ call procM6(?,?) }";

			stat = conn.prepareCall(sql);

			stat.setString(1, buseo);
			stat.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);

			stat.executeQuery();

			rs = (ResultSet) stat.getObject(2);

			System.out.println("== 보너스 지급 내역 ==");
			System.out.println("[직원명]\t[지급액]");

			while (rs.next()) {
				System.out.printf("%s\t%,10d원\n", rs.getString("name"),
						// the column value; if the value is SQL NULL, thevalue returned is 0
						rs.getInt("bonus"));
			}

			rs.close();
			stat.close();
			conn.close();


		} catch (Exception e) {
			e.printStackTrace();
		}

🎇 자바 프로그램에서 클래스의 호출 순서 ⭐


🙋‍♂️ 마무리

JDBC 중요! 반복해서 보기

1개의 댓글

comment-user-thumbnail
2023년 7월 12일

감사합니다 큰 도움되었습니다

답글 달기