JDBC
[JDBC]days05- CallableStatement , 자바에서 커서 이용
애플쩀
2022. 5. 11. 11:35
CallableStatement
프로시저를 호출할 때 사용한다.
Insert , update, delete 사용시 편리하다.
자바에서 호출할때
call 프로시저명 (매개변수)
[오라클] 커서 - 자바에서 출력하고 닫도록
create or replace procedure up_selectemp
(
pdeptno in dept.deptno%type
,pCursor out SYS_REFCURSOR -- out : 결과물을 커서에 담아서 출력
)
is
vsql varchar2(1000);
begin
vsql := 'SELECT deptno, empno, ename, job, hiredate ';
vsql := vsql||' from emp ';
vsql := vsql||' where deptno = :pdeptno';
--동적쿼리 실행, 얘가 실행되면 결과물이 커서에 담긴다
open pCursor for vsql --동적쿼리를 쓸때는 open for문 쓰는 것 기억
using pdeptno;
end;
자바
- 프로시저를 호출call, 매개변수는 두개(커서,부서번호)
String sql="{call UP_SELECTEMP(?,?)}"; - 출력용매개변수이면서 커서타입을 받겠다.
cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR); - 커서에 결과물이 담겨져 있기 때문에 resultSet으로 변환하고 반환한다 .
rs=(ResultSet)cstmt.getObject(2);
package days06;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import com.util.DBconn;
import days02.EmpDTO;
public class Prac {
public static void main(String[] args) {
//UP_SELECTEMP;
System.out.print("> deptno input ? ");
Scanner scanner = new Scanner(System.in);
int deptno = scanner.nextInt();
//원래 int인데 String으로 날려도 전혀 상관 없음
//오라클은 홑따옴표를 사용하기 때문
Connection con = null;
CallableStatement cstmt= null;
ResultSet rs= null;
ArrayList<EmpDTO> list = null;
String sql ="{ call UP_SELECTEMP( ? ,? ) }";
con = DBconn.getConnection();
try {
cstmt = con.prepareCall(sql);
// ?
cstmt.setInt(1, deptno);
// ? OUT 출력용 매개변수 설정
cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
// rs= cstmt.executeQuery(); 이게 아니라 두번째 파라미터 값인 커서로 돌려준다
cstmt.executeQuery();
rs = (ResultSet) cstmt.getObject(2); //다운캐스팅 작업
if(rs.next()) {
list= new ArrayList<EmpDTO>();
EmpDTO dto = null;
do {
dto = new EmpDTO( );
dto.setEmpno(rs.getInt("empno"));
dto.setDeptno(deptno);
dto.setEname(rs.getString("ename"));
dto.setJob(rs.getString("job"));
dto.setHiredate(rs.getDate("hiredate"));
list.add(dto);
}while(rs.next());
}//if
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
rs.close();
cstmt.close();
DBconn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}//finally
printEmpInfo(list);
}//main
private static void printEmpInfo(ArrayList<EmpDTO> list) {
if(list == null) {
System.out.println("사원이 존재하지 않습니다");
}else {
Iterator<EmpDTO> ir = list.iterator();
while (ir.hasNext()) {
EmpDTO dto = ir.next();
System.out.println(dto);
}
}
}}
오라클 아이디 중복 체크
create or replace procedure up_logon2
(
pempno in number --id in
, pename in varchar2 --pwd in
, plogoncheck out number -- 1,2,0 out
)
is
vempno number(1) ; -- 0 1(아이디존재)
vename emp.ename%type;
begin
select count(*) into vempno
from emp
where empno = pempno;
if vempno = 0 then
plogoncheck := 1; --아이디가 존재하지 않는 경우 (아이디 사용 가능)
else
select ename into vename
from emp
where empno = pempno;
if pename = vename then
plogoncheck := 0; -- 로그인 성공
else
plogoncheck := 2; --비밀번호가 틀린 경우
end if;
end if;
--exception
end;
자바
나중에 Query+Ajax에서 처리
package days06;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Scanner;
import com.util.DBconn;
import days02.EmpDTO;
public class Prac {
public static void main(String[] args) {
package days06;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Scanner;
import com.util.DBconn;
import days02.EmpDTO;
public class Prac {
public static void main(String[] args) {
System.out.println("중복체크할 id ,passwd 입력 ");
Scanner sc=new Scanner(System.in);
int empno=sc.nextInt();
String ename=sc.next();
Connection conn=null;
CallableStatement cstmt=null;
String sql="call up_logon2(?,?,?)";
conn=DBconn.getConnection();
int logonCheck=0;
try {
cstmt=conn.prepareCall(sql);
cstmt.setInt(1,empno);
cstmt.setString(2, ename);
//출력용파마리터
cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.INTEGER);
cstmt.executeQuery();
logonCheck=(int)cstmt.getObject(3);
if(logonCheck==1) {
System.out.println("아이디존재 x");
}else if(logonCheck==0) {
System.out.println("로그인성공");
}else if (logonCheck==2) {
System.out.println("비밀번호잘못");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
cstmt.close();
DBconn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}}
}}
처음에 제대로 출력결과가 나오지 않았다.
이유 => logonCheck=(int)cstmt.getObject(3);
이부분을 빠트려서 출력용 logonCheck 를 받아오지 않았던것
중요
cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.INTEGER);
cstmt.executeQuery();
logonCheck=(int)cstmt.getObject(3);