oracle 11일차 제어문/반복문/커서/ +java sql develope 데이터 연동

최정민·2023년 12월 19일

ORACLE

목록 보기
11/13

제어문

PL/SQL은 여러 가지 제어 구조를 이용하여 문장들을 논리적 흐름을 변경할 수 있다.
조건에 의해 분기하는 선택문과 반복된 문장을 한번 기술하고도 여러 번 수행하도록 하는 반복문이 있다.

1)IF ~ THEN ~ END IF

특정 조건을 만족하면 어떤 처리를 하고, 그렇지 않으면 아무 처리도 하지 않는다.
IF 조건문 THEN
조건처리;
END IF;

급여를 구하는 예제

DECLARE 
    --%ROWTYPE 속성으로 로우를 저장할 수 있는 레퍼런스 변수 선언
    vemployees employees%ROWTYPE;
    vsalary NUMBER(8,2);
BEGIN
    DBMS_OUTPUT.PUT_LINE('사번 / 이름 / 급여 ');
    DBMS_OUTPUT.PUT_LINE('-----------------');
    -- pat 사원의 전체 정보를 로우 단위로 얻어와 vemployees에 저장한다.
    SELECT * INTO VEMPLOYEES
    FROM EMPLOYEES
    WHERE FIRST_NAME = 'Pat';
    --커미션이 NULL 일 경우 이를 0으로 변경해야 올바른 급여 계싼이 가능하다
    IF(vemployees.commission_pct IS NULL) THEN
     vemployees.commission_pct := 0;
    END IF;
    
    --스칼라 변수에 급여를 계산할 결과를 저장한다.
    vsalary := vemployees.salary + (vemployees.salary * vemployees.commission_pct);
    --레퍼런스 변수와 스칼라 변수에 저장된 값을 출력한다.
    DBMS_OUTPUT.PUT_LINE('사원번호:' || vemployees.employee_id||
                        '/사원명 :' || vemployees.first_name ||
                        '/급여 :' || to_char(vsalary,'$999,999'));
END;
/

2)IF ~ THEN ~ ELSE ~ END IF

조건을 만족할 떄의 처리와 그렇지 않을 때의 처리, 즉 두 가지 처리문 중에서 한 개를 선택해야 할 경우 사용한다.

IF 조건문 THEN
조건처리1;
ELSE
조건처리2;
END IF;

DECLARE 
    --%ROWTYPE 속성으로 로우를 저장할 수 있는 레퍼런스 변수 선언
    vemployees employees%ROWTYPE;
    vsalary NUMBER(8,2);
BEGIN
    DBMS_OUTPUT.PUT_LINE('사번 / 이름 / 급여 ');
    DBMS_OUTPUT.PUT_LINE('-----------------');
    -- pat 사원의 전체 정보를 로우 단위로 얻어와 vemployees에 저장한다.
    SELECT * INTO vemployees
    FROM EMPLOYEES
    WHERE FIRST_NAME = 'Jack';
    --커미션이 NULL 일 경우 이를 0으로 변경해야 올바른 급여 계산이 가능하다
    IF(vemployees.commission_pct IS NULL) THEN
     vsalary := vemployees.salary;
     ELSE
     vsalary := vemployees.salary + (vemployees.salary * vemployees.commission_pct);
    END IF;
    
    
    --레퍼런스 변수와 스칼라 변수에 저장된 값을 출력한다.
    DBMS_OUTPUT.PUT_LINE('사원번호:' || vemployees.employee_id||
                        '/사원명 :' || vemployees.first_name ||
                        '/급여 :' || to_char(vsalary,'$999,999'));
END;
/  

3) IF ~ THEN ~ ELSIF ~ ELSE ~ END IF

여러 개 조건에 따라 처리도 여러 개일 때 사용하는 다중 IF문이다.

IF 조건문2 THEN
조건처리1;
ELSIF 조건문3 THEN
조건처리2;
ELSIF 조건문3 THEN
WHRJSCJFL3;
ELSE
조건처리n;
END IF;

DECLARE
 --%ROWTYPE 속성으로 로우를 저장할 수 있는 레퍼런스 변수 선언
 vemployees employees%rowtype;
 vdepartment_NAME departments.department_name%type;
BEGIN
 DBMS_OUTPUT.PUT_LINE('사번/이름/부서번호/부서명');
 DBMS_OUTPUT.PUT_LINE('----------------------');
 --사원번호가 192 사원의 전체 정보를 로우 단위로 얻어와 vemployees에 저장한다
 select * into vemployees from employees where employee_id = 192;
 
 IF(vemployees.department_id = 10) THEN 
 vdepartment_name := 'Administration';
 ELSIF(vemployees.department_id = 20) THEN 
 vdepartment_name := 'Marketing';
 ELSIF(vemployees.department_id = 30) THEN 
 vdepartment_name := 'Purchasing';
 ELSIF(vemployees.department_id = 40) THEN 
 vdepartment_name := 'Human Resources';
 ELSIF(vemployees.department_id = 50) THEN 
 vdepartment_name := 'Shipping';
 END IF;
 DBMS_OUTPUT.PUT_LINE(vemployees.employee_id || '/' || vemployees.first_name||'/'||
    RPAD(vemployees.department_id,4)||'/'||vdepartment_name);
END;
/

RPAD 함수

DBMS_RANDOM.VALUE

-랜덤한 숫자를 생성한다.
-형식 : DBMS_RANDOM.VALUE(최소 범위의 숫자, 최대 범위의 숫자)

DBMS_RANDOM.STRING

-랜덤한 문자열을 생성한다.
-형식 : DBMS_RANDOM.STRING(옵션문자, 길이수)

-옵션문자
'u','U' 대문자 'l', 'L' 소문자 'x','X' 영문자와 숫자 혼합
'p','P' 문자 혼합 'a','A' 대소문자 구분없는 영문자

(예제) SELECT DBMS_RANDOM.STRING('U',1) FROM DUAL; -- 1개의 임이의 문자
SELECT DBMS_RANDOM.STRING('A',2) FROM DUAL; --대소문자 관계없이 2개의 임이의 문자

  ![](https://velog.velcdn.com/images/aksenfdl456/post/54e8c86d-ac38-40bf-9d37-86380f86b4aa/image.png)

-DBMS_RANDOM.VALUE
SELECT DBMS_RANDOM.VALUE(1,5) FROM DUAL;
SELECT ROUND(DBMS_RANDOM.VALUE(1,5)) FROM DUAL;
SELECT TRUNC(DBMS_RANDOM.VALUE(1,5)) FROM DUAL;
--임의이 부서번호를 얻고자 할때
SELECT ROUND(DBMS_RANDOM.VALUE(10,270),-1) FROM DUAL;

--예제
select dbms_random.string('u',1) from dual; -- 1개의 임의의 문자
select dbms_random.string('a',2) from dual; -- 대소문자 관계없이 2개의 임의의 문자
select dbms_random.string('x',8) from dual; -- 영문자와 숫자혼합 8개의 임의의 문자

DECLARE
 vsalary NUMBER := 0;
 vdepartment_id NUMBER := 0;
BEGIN
 SELECT ROUND(DBMS_RANDOM.VALUE(10,280),-1) INTO vdepartment_id FROM DUAL;
 
 SELECT salary INTO vsalary
 FROM employees
 WHERE department_id = vdepartment_id AND ROWNUM = 1;
 DBMS_OUTPUT.PUT_LINE('부서번호:' || vdepartment_id || '급여:' || vsalary);
 
 IF vsalary BETWEEN 1 AND 6000 THEN
 DBMS_OUTPUT.PUT_LINE('낮음');
ELSIF vsalary BETWEEN 6001 AND 10000 THEN
 DBMS_OUTPUT.PUT_LINE('중간');
ELSIF vsalary BETWEEN 10001 AND 20000 THEN
 DBMS_OUTPUT.PUT_LINE('높음');
ELSE
 DBMS_OUTPUT.PUT_LINE('최상위');
END IF;

EXCEPTION
WHEN NO_DATA_FOUND THEN
 DBMS_OUTPUT.PUT_LINE(vdepartment_id ||' 부서에 해당 사원이 없습니다.');
END;
/

4)반복문

반복문은 SQL 문을 반복적으로 여러 번 실행하고자 할 때 사용한다.
PL/SQL에서는 다양한 반복분이 사용된다.

-조건 없이 반복 작업을 제공하기 위한 BASIC LOOP문
-COUNT를 기본으로 작업의 반복 제어를 제공하는 FOR LOOP문
-조건을 기본으로 작업의 반복 제어를 제공하는 WHILE LOOP문
-LOOP을 종료하기 위한 EXIT문

BASIC LOOP 문

LOOP
statement1;
statement2;
EXIT[WHEN condition];
END LOOP;

loop에서 end loop 사이를 계속 반복해서 실한다. 이러한 루프를 무한 루프라 하며, 여기서 빠져나가려면 exti문을 사용한다. exit문을 이용하여 루프를 종료할 수 있다. 조건에 따라 루프를 종료할 수 있도록 WHEN 절을 덧붙일 수 있다.

실행상의 흐름이 LOOP에 도달할 때 마다 그와 짝을 이루는 LOOP 문으로 제어가 되돌아간다.
여기서 빠져나가려면 EXIT 문을 사용한다.

--LOOP 반복문을 통한   구구단 3단 출력
DECLARE 
    vn_base_num NUMBER :=3;
    vn_cnt NUMBER :=1;
BEGIN
 DBMS_OUTPUT.PUT_LINE('***** 구구단 3단 *****');
 LOOP
 DBMS_OUTPUT.PUT_LINE(vn_base_num|| '*'||vn_cnt|| '='||vn_base_num * vn_cnt);
 vn_cnt:= vn_cnt + 1;
 --EXTI WHEN vn_cnt > 9;
 IF vn_cnt > 9 THEN
   EXIT;
  END IF;
 END LOOP;
END;
/

FOR LOOP 문

FOR LOOP는 반복되는 횟수가 정해진 반복문을 처리
사용되는 인덱스는 정수로 자동 선언되므로 따로 선언할 필요 X
LOOP을 반복할 때 마다 자동적으로 1씩 증가 또는 감소한다. REVERSE는 1씩 감소함을 의미

FOR index_counter IN[REVERSE] lower_bound..upper_bound LOOP
statement1;
statement2;
END LOOP;

DECLARE
    vdepartments departments%rowtype;
begin
    dbms_output.put_line('부서번호 / 부서명 / 지역명');
    dbms_output.put_line('-----------------------');
    --변수 cnt는 1부터 1씩 증가하다가 27에 도달하면 반복문에서 벗어난다.
    for cnt in 1..27 loop
    select * into vdepartments from departments
    where departments_id = 10*cnt;
    dbms_output.put_line(vdepartments.department_id ||'/'||
    vdepartments.department_name || '/'|| vdepartments.location_id);
  END LOOP;
END;
/

WHILE LOOP문

제어 조건이 TRUE인 동안만 이렬ㄴ의 문장을 반복하기 위해 WHILE LOOP 문장을 사용한다.
조건은 반복이 시작될 때 체크하게 되어 LOOP내의 문장이 한번도 수행되지 않을 경우도 있다.
LOOP을 시작할 때 조건이 FALSE 이면 반복 문장을 탈출하게 된다.

WHILE 조건문 LOOP
statement1;
statement2;
END LOOP;

DECLARE 
    i NUMBER := 1;
    vdepartments departments%rowtype;
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호/ 부서명/ 지역명');
    DBMS_OUTPUT.PUT_LINE('----------------------');
    WHILE I <= 27 LOOP
    IF I MOD 2 = 0 THEN
    SELECT * INTO vdepartments from departments WHERE department_id = 10* i;
    DBMS_OUTPUT.PUT_LINE(vdepartments.department_id || '/'||
    vdepartments.department_name || '/' || vdepartments.location_id);
    END IF;
    i := i + 1;
    END LOOP;
END;
/

커서

오라클 서버에서는 SQL 문을 실행할 때마다 처리(Parse, Excution)를 위한 메모리공간 (이 공간을 이후 부터 SQL 커서로 지칭.)을 사용한다. 즉 사용자강 요청하는 데이터를 데이터베이스 버퍼, 캐쉬에서 커서로 복사 해 온 후 커서에서 원하는 데이터를 추출하여(Fetch) 원하는 작업을 하게된다는 뜻이다. 이 메모리 공간을 Private SQL Area 라고도 부름.

다시말해 커서란 특정 SQL 문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터로, 커서를 사용하면 처리된 SQL 문장의 결과 집합에 접근할 수 있다. 커서의 종류에는 묵시적 커서와 명시적 커서가 있다. 묵시적 커서란 오라클 내부에 자동으로 생성하는 커서, 명시적 커서는 사용자가 직접 정의해서 사용하는 커서를 말한다. 커서는 "커서 열기(OPEN) - 패치(fetch) - 커서닫기(close)" 3단계로 진행된다.

ㆍDECLARE CURSOR (커서 선언)

사용할 커서를 선언부에 직접 정의해야 한다. 사용할 커서에 이름을 부여하고 이 커서에 대한 쿼리를 선언
형식 CURSOR 커서명 IS 커서에 담고 싶은 내용을 가져오는 서브쿼라;
예 CURSOR C1 IS SELECT * FROM Departments;

ㆍOPEN CURSOR(커서 열기)

질의를 수행하고 검색 조건을 충족하는 모든 행으로 구성된 결과셋(커서 선언 시 기술했던 서브쿼리를 수행해서 데이터를 커서로 가져오는 과정)을 생성하기 위해 CURSOR를 OPEN한다.
CURSOR는 이제 결과 셋에서 첫번째 행을 가르킴
형식 OPEN 커서명;
예 OPEN C1;

ㆍFETCH CURSOR( 패치 단계에서 커서 사용)

정의한 커서를 열고 난 후에야 SELECT 문의 결과로 반환되는 로우에 접근할 수있다.
결과 집합의 로우 수는 보통 1개 이상이므로 전체 로우에 접근하기 위해서는 반복문을 사용해야 한다.

  • FETCH문은 셋에서 로우 단위로 데이터를 읽어들임.
    -FETCH후에 CURSOR는 결과 셋에서 다음 행으로 이동
    형식 FETCH 커서명 INTO 변수들
    INTO{variable1 [, 2 valiable2,....];
    예 LOOP
    FETCH C1 INTO vdepartments.department_id, vdepartments.department_name,
    vdepartments.location_id;
    EXIT WHEN C1%NOTFOUND;
    ENX LOOP'
    얻어진;

여러 개의 행에 대한 결과값을 모두 처리하려면 반복문에 FETCH문을 기술해야한다.
NOTFOUND 는 커서의 상태를 알려주는 속성 중에 하나인데 커서 영역의 자료가 모두 FETCH 되었다면 TRUE를 되돌린다. 즉 커서 C1 영역의 자료가 모두 FETCH되면 반복물은 탈출

-커서의 상태

%NOT FOUND 커서 영역의 자료가 모두 FETCH되었다면 TRUE
%ROWCOUNT 커서가 얻어 온 레코드의 개수
%IS OPEN 커서가 OPen 된 상태이면 TRUE
%FOUND 커서 영역에 FETCH 되지 않은 자료가 있다면 TRUE

ㆍCLOSE CURSOR(커서 닫기)

CLOSE 문장은 CURSOR를 사용할 수 없게 하고 결과 셋의 정의를 해제한다.
형식 CLOSE cursor_name;
예 CLOSE C1;

DECLARE
vdepartments departments%rowtype;
curs

명시적 커서

--명시적 커서
DECLARE
    vdepartments departments%rowtype;
    CURSOR C1 -- 커서의 이름(커서 선언)
    IS
    SELECT department_id, department_name, location_id
    from departments; -- 부서테이블의 전체 내용을 조회
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호/ 부서명/ 지역명');
    DBMS_OUTPUT.PUT_LINE('----------------------------------');
    
    OPEN C1;
    --오픈한 C1 커서가 SELECT 문에 의해 검색된 한개의 행의정보를 읽어온다.
    
    LOOP --읽어온 정보는 INTO 뒤에 기술한 변수에 저장
      FETCH C1 INTO vdepartments.department_id, vdepartments.department_name,
      vdepartments.location_id;
      EXIT WHEN C1%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE(vdepartments.department_id ||' '||
      RPAD(vdepartments.department_name, 20) || ' ' || vdepartments.location_id);
    END LOOP;
    CLOSE C1;
END;
/

CURSOR와 FOR LOOP(묵시적으로 CURSOR에서 행을 처리한다.)
LOOP에서 각 반복마다 CURSOR를 열고 행을 인출(FETCH)하고 모든 행이 처리되면 자동으로
CURSOR 가 CLOSE되므로 사용하기가 편리하다.
형식 FOR record_name IN cursor_name LOOP
--명시적 커서의 OPEN, FETCH 가 자동적으로 수행됨.
statement1;
statement2;
END LOOP -- 루프문을 빠져 나갈 때 자동적으로 커서가 CLOSE 됨.

묵시적 커서

--묵시적 커서
DECLARE
    vdepartments departments%ROWTYPE;
    CURSOR C1
    IS
    SELECT * FROM departments;
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호/부서명/지역명');
    DBMS_OUTPUT.PUT_LINE('------------------------');
    FOR vdepartments IN C1 LOOP
      DBMS_OUTPUT.PUT_LINE(vdepartments.department_id || ''||
     RPAD(vdepartments.department_name,20)||''||vdepartments.location_id);
    END LOOP;
END;
/
DECLARE
   vdepartments departments%ROWTYPE;
BEGIN
   DBMS_OUTPUT.PUT_LINE('부서번호/부서명/지역명');
   DBMS_OUTPUT.PUT_LINE('------------------------');
   FOR vdepartments IN (select * from departments) LOOP 
     DBMS_OUTPUT.PUT_LINE(vdepartments.department_id || ''||
    RPAD(vdepartments.department_name,20)||''||vdepartments.location_id);
   END LOOP;
END;
/

--부서 번호를 임의의 수로 얻어 레코드를 출력하도록 쿼리를 작성한다.
DECLARE 
    vrandomid employees.department_id%type; --임의의 부서번호
    vsalarystring VARCHAR2(20);  --급여 등급
    --커서 선언 시 매개변수를 명시할 수 있다. CURSOR 커서명(매개변수) IS 쿼리문.
    CURSOR cur_employees(vdepartment_id employees.department_id%type)
    is
    select salary,first_name from employees where department_id = vdepartment_id;
begin
    --임의의 부서번호를 얻어 출력
    SELECT ROUND(DBMS_RANDOM.VALUE(10,270),-1) INTO vrandomid FROM DUAL;
    DBMS_OUTPUT.PUT_LINE('부서번호 : ' || vrandomid ) ;
    
    --그 부서번호가 120에서 270번까지 소속된 사원이 없기에 제어.
    IF vrandomid between 120 and 270 THEN
    DBMS_OUTPUT.PUT_LINE(vrandomid || '부서에 해당 사원이 없습니다.');
    RETURN; --블록을 종료
 END IF;
 
 DBMS_OUTPUT.PUT_LINE('사원명/ 급여/ 급여수준');
 DBMS_OUTPUT.PUT_LINE('-----------------------');
 
 FOR vemployees IN cur_employees(vrandomid) LOOP
  IF vemployees.salary BETWEEN 1 AND 6000 THEN
    vsalarystring:='낮음';
  ELSIF vemployees.salary BETWEEN 6001 AND 10000 THEN
   vsalarystring:='중간';
  ELSIF vemployees.salary BETWEEN 10001 AND 20000 THEN
   vsalarystring:='높음';
  ELSE
   vsalarystring:='최상위';
  END IF;
  DBMS_OUTPUT.PUT_LINE(RPAD(vemployees.first_name,6)|| RPAD(vemployees.salary,5)||'/'|| vsalarystring);
 END LOOP;
END;
/

결과를 보면 실행 할 때마다 랜덤으로 부서번호값을 출력하여 부서의 해당 사원의 사원명/급여/급여수준을 나타내는 것을 확인할 수 있다.


java eclips SQL develope 데이터 연동

java로 sql develope 연동해서 select 문으로 테이블 조회하고 insert문으로 학과테이블 데이터 추가하기

package subject_management;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/*	DAO(Date Access Object) 클래스가 데이터 처리의 궁극적인 단계이다.
 * 
 *  CRUD 프로그램 구현
 *  기본적인 데이터 처리 기능인 입력(Create, insert), 조회(read(또는 Retrieve), Select), 수정(Update),
 *  삭제(Delete) 기능을 구현한 데이터베이스 프로그램.
 *  
 * */
public class SubjectDAO {
	//데이터베이스 연결 관련 상수 선언
	private static final String JDBC_URL ="jdbc:oracle:thin:@127.0.0.1:1521/xepdb1";
	private static final String USER = "javauser";
	private static final String PASSWD = "java1234";
	
	//클래스 자신의 타입으로 정적 필드 선언
	private static SubjectDAO instance = null;
	
	
	//외부에서 호출할 수 있는 정적 메소드인 getInstance() 선언하여 인스턴스를 반환.
	public static SubjectDAO getInstance() {
		if( instance == null) {
			instance = new SubjectDAO();
		}
		return instance;
	}
	
	//외부에서 new 연산자로 생성자를 호출할 수 없도록 막기 위해 접근 제한자 (private) 설정
	private SubjectDAO() {
		try {
			Class.forName("oracle.jdbc.OracleDriver");
		}catch(ClassNotFoundException cnfe) {
			cnfe.printStackTrace();
		}
	}
	
	private Connection getConnection() throws SQLException{
		Connection con = DriverManager.getConnection(JDBC_URL, USER, PASSWD);
		return con;
	}
	
	
	/*getSubjectTotal() 메서드: 학과 테이블에서 모든 레코드를 반환 메서드
	 * @return ArrayList<SubjectVO> 자료형 리턴.
	 * */
			
	
	public ArrayList<SubjectVO> getSubjectTotal(){
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		SubjectVO svo = null;
		ArrayList<SubjectVO> list = new ArrayList<SubjectVO>();
		
		StringBuffer sql = new StringBuffer();
		sql.append("select no, s_num, s_name from subject ");
		sql.append("order by no");
		
		try {
			con = getConnection();
			pstmt = con.prepareStatement(sql.toString());
			rs = pstmt.executeQuery();
			
			//ResultSet의 결과에서 모든 행을 각각의 SubjectVO 객체에 저장
			while(rs.next()) {
				//한행의 학과 정보를 저장할 VO 객체 생성
				svo = new SubjectVO();
				//한 행의 학과 정보를 VO 객체에 저장
				svo.setNo(rs.getInt("no"));
				svo.setS_num(rs.getString("s_num"));
				svo.setS_name(rs.getString("s_name"));
				//↑VO담는 작업
				//ArrayList 객체에 원소로 추가
				list.add(svo);
			}
		}catch(SQLException se) {
			System.out.println("조회에 문제가 있어 잠시 후에 다시 진행해 주세요.");
			se.printStackTrace();
		}catch (Exception e) {
			System.out.println("error = [ " + e.getMessage() +" ]");
		}finally {
			try {
				if(rs != null) rs.close();
				if(pstmt != null) pstmt.close();
				if( con != null) con.close();
			}catch(SQLException e) {
				System.out.println("디비 연동 해제 error = [ " + e +" ]");
			}
		}
		return list;
	}
	 /* getSubjectNum() 메서드: 학과번호 자동 구하기.
	  * @return String 자료형 리턴.
	  * */
	public String getSubjectNum() {
		return null;
	}
	
	/*subjectInsert() 메서드: 학과 테이블에 데이터 입력.
	 * @param svo SubjectVO 클래스
	 * @return boolean 자료형 리턴.
	 * */	
	
	public boolean subjectInsert(SubjectVO svo) {
		StringBuffer sql = new StringBuffer();
		sql.append("insert into subject(no, s_num, s_name) ");
		sql.append("values(subject_seq.nextval, ?, ?)");
		
		Connection con = null;
		PreparedStatement pstmt = null;
		boolean success = false;
		try {
			con = getConnection();
			pstmt = con.prepareStatement(sql.toString());
			pstmt.setString(1, svo.getS_num()); //첫번째 ?(바인딩 변수) 설정값 - 학과번호
			pstmt.setString(2, svo.getS_name()); //두번째 ?(바인딩 변수) 설정값 - 학과명
			
			int i = pstmt.executeUpdate(); //쿼리문 실행 - 결과값은 입력된 행의 수 반환.
			if(i == 1) {
				success = true;
			}
		}catch(SQLException se) {
			System.out.println("입력에 문제가 있어 잠시 후에 다시 진행해 주세요.");
			se.printStackTrace();
		}catch(Exception e) {
			System.err.println("error = [ " + e.getMessage() + " ]");
		}finally {
			try {
				if(pstmt != null) pstmt.close();
				if(con != null) con.close();
			}catch(SQLException e) {
				System.out.println("디비 연동 해제 error = [ " + e + " ]");
			}
		}
		return success;
	}

	 
}
package subject_management;

import java.util.ArrayList;

import academic_management.MenuViewer;

public class SubjectManagement {
	private SubjectDAO dao = SubjectDAO.getInstance();
	
	public void read(String mode) {
		ArrayList<SubjectVO> svo = dao.getSubjectTotal();
		System.out.println("\n**** subject 테이블 데이터 출력 ****");
		System.out.println("번호\t학과번호\t학과명");
		if(svo.size() > 0) {
			//for(int i = 0 ; i < svo.size(); i++){
			//SubjectVO sub = svo.get(i);
			for(SubjectVO sub : svo) {
				System.out.print(sub.getNo()+ "\t");
				System.out.print(sub.getS_num()+ "\t");
				System.out.println(sub.getS_name()+ "\t");
			}
		}else {
			System.out.println("학과 정보가 존재하지 않습니다.");
		}
	}
	
	private SubjectVO inputData(String mode) {
		String s_num=null, s_name = null;
	
	
	/*추후 입력 시 학과 번호를 자동으로 부여하도록 설정
	 * SubjectDAO 클래스에서 getSubjectNum() 메서드가 정의되면 아래의 입력 부분을 주석 해제한다.
	 * if(mode.equals("input")) {
	 * System.out.print("학과코드 입력 : ");
	 * s_num = dao.getSubjectNum();
	 * System.out.println(s_num);*/
	
	 /*SubjectDAO 클래스에서 getSubjectNum() 메서드가 정의되면 아래의 입력 부분을 주석 처리한다.*/
	 System.out.print("학과코드 입럭 : ");
	 s_num = MenuViewer.keyboard.nextLine();
	 
	 if(!mode.equals("delete")) {
		 System.out.print("학과명 입력 : ");
		 s_name = MenuViewer.keyboard.nextLine();
	 }
	
	 SubjectVO sub = new SubjectVO(0, s_num, s_name);
	 return sub;
	}	
	public void create() {
		SubjectVO svo = inputData("input");
		boolean result = dao.subjectInsert(svo);
		if(result) {
			System.out.println("학과 데이터 입력 성공.");
		}else {
			System.out.println("학과 데이터 입력 실패.");
		}
	}
}

sql develope를 실행시켜 학과테이블을 조회해보면 데이터가 추가된 것을 확인할 수 있다.

--자동으로 학과 번호 얻기

select nvl(lpad(max(to_number(ltrim(s_num,'0')))+1,2,'0'),'01')
as subjectNum from subject;
 /* getSubjectNum() 메서드: 학과번호 자동 구하기.
	  * @return String 자료형 리턴.
	  * */
	
	public String getSubjectNum() {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String subjectNumber="";
		//쿼리문 그대로 가지고 와서 붙여넣기 해 주세요.
		StringBuffer sql = new StringBuffer();
		sql.append("select nvl(lpad(max(s_num)+1,2,'0'),'01') ");
		sql.append("as subjectNum from subject");

		try {
		con = getConnection();
		pstmt = con.prepareStatement(sql.toString());
		rs = pstmt.executeQuery();
		if(rs.next()) {
			subjectNumber = rs.getString("subjectNum");
		}
	}catch(SQLException se) {
		System.err.println("쿼리 getSubjectNum error = [" + se.getMessage() + " ]");
		se.printStackTrace();
	}catch(Exception e) {
		System.out.println("error = [ " + e + " ] ");
	}finally {
		try {
			if(rs != null) rs.close();
			if(pstmt != null) pstmt.close();
			if(con != null) con.close();
		}catch(SQLException se) {
			System.out.println("디비 연동 해제 error = [ " + se + " ]");
		}
	}
	return subjectNumber;
/*추후 입력 시 학과 번호를 자동으로 부여하도록 설정
	 * SubjectDAO 클래스에서 getSubjectNum() 메서드가 정의되면 아래의 입력 부분을 주석 해제한다.*/
	  if(mode.equals("input")) {
	  System.out.print("학과코드 입력 : ");
	  s_num = dao.getSubjectNum();
	  System.out.println(s_num);
	  }
	/* SubjectDAO 클래스에서 getSubjectNum() 메서드가 정의되면 아래의 입력 부분을 주석 처리한다.*/
	/* System.out.print("학과코드 입럭 : ");
	 s_num = MenuViewer.keyboard.nextLine();*/

위의 코드에서 윗부분 주석을 해제하고 아래 코드를 주석을 걸면 된다.

위 캡쳐를 보면 학과코드가 자동으로 입력되어 있는 것을 확인 할 수 있다.

profile
개발 일지

0개의 댓글