DataBase+SQL

PL/SQL

campanula 2023. 6. 26. 17:43

자주 사용하는 명령을 PL/SQL 구문을 이용하여 데이터베이스에 저장하고 필요할 때 호출하여 사용하는 방법 연습

1)PL/SQL: Oracle's Procedural Language extension to SQL의 약자

SQL문장에서 변수  정의, 조건처리(IF), 반복처리(LOOP, WHILE, FOR)등을 지원

DB에 직접 탑재되어 컴파일, 실행 => 성능 우수, DB 관련 처리를 할 때 수많은 기능을 제공, 일반 프로그래밍 언어적인 요소를 거의 다 가지고 있어서 실무에서 요구되는 절차적인 데이터 처리를 다 할 수 있음. 특히 SQL과 연동되어 막강할 기능 구현 가능

 

PL/SQL은 SQL에 없는 기능 제공

  • 변수 선언 가능
  • 비교 처리 가능
  • 반복 처리 가능

PL/SQL 기본 단위: 블록(BLOCK)=> 선언부, 실행부, 예외처리부 구성

                                                     => 이름이 없는 블록(익명 블록: 처음부터 마지막까지 한꺼번에 정의), 이름이 있는 블록                                                             (함수, 프로시저, 패키지) 구분

 

DECLEARE
	선언부(DECLARE SECTION)
    -변수나 상수를 선언
BEGIN
	실행부(EXECUTABLE SECTION)
    SQL문
    제어문, 반복문
    커서
EXCEPTION 
	예외 처리부(EXCEPTION SECTION)
END;
/

 

장점

  • 프로그램의 모듈화: 특정 프로그램을 Procedure, function, package등의  프로그램으로 만들어 여러 응용 프로그램을 만들시 공통으로 이용 및 관리 할 수 있다.
  • 관리의 용이
  • 네트워크 입출력 감소: 프로시저 등을 실행하는 구문만 데이터베이스에 보낼 수 있어 네트워크 입출력을 현격하게 줄일 수 있다.

특징

  • PL/SQL 블록 내에서는 한 문장이 종료할 때마다 세미콜론(;)을 사용
  • END 뒤에 ;을 사용하여 하나의 블록이 끝났다는 것을 명시
  • DECLARE나 BEGIN이라는 키워드로 PL.SQL 블록이 시작하는 것을 알 수 있다.
  • 단일 행 주석은 --이고 여러 행 주석을 /**/이다.
  • PL/SQL 블록은 행에 /가 있으면 종료

 

자바
자료형 변수 = 값;		--대입연산자
비교 연산자 ==		--비교

오라클
변수 자료형 := 값;	--대입
비교 연산자 =		--비교

SELECT 컬럼1, 컬럼2 INTO 변수1, 변수2	--변수에 데이터 담기
FROM 테이블
WHERE 조건문

 

모든 문장의 종결 기호는 세미콜론으로 명시, 대입 연산자로는 := 사용, 대입 연산자는 변수의 선언 시 및 변수의 대입에 이용

변수 자료형 := 값;

SELECT문에 의해 추출되는 DATA는 INTO절의 변수에 저장해서 처리

 

--'Hello World!' 출력
BEGIN
    DBMS_OUTPUT.PUT_LINE('Hello World!');       --DBMS_OUTPUT: Package, 오라클 문장 작은 따옴표
END;
/

 

보기 - DBMS 출력 - +에서 사용자 설정

 

DECLARE
    VEMPLOYEE_ID NUMBER(6);     --변수 자료형
    VFIRST_NAME VARCHAR2(20);
BEGIN
    VEMPLOYEE_ID := 105;
    VFIRST_NAME := 'David';
    
    DBMS_OUTPUT.PUT_LINE('사번 / 이름');
    DBMS_OUTPUT.PUT_LINE('-----------');
    DBMS_OUTPUT.PUT_LINE(VEMPLOYEE_ID || ' / ' || VFIRST_NAME);
END;
/

 

1) 변수

IDENTIFIER [CONSTANT] DATATYPE [NOT NULL] [:=|DEFAULT EXPRESSION];

 

구문 설명
IDENTIFIER 변수의 이름
CONSTANT 변수의 값을 변경할 수 없도록 제약
DATATYPE 자료형(데이터 타입)을 기술
-변수 데이터 타입: SQL 타입(NUMBER, CHAR, VARCHAR2,DATE,...) 과 PL/SQL 타입
-PL/SQL 데이터 타입: BOOLEAN, BINARY_INTEGER
NOT NULL 값을 반드시 포함하도록 하기 위해 변수를 제약
EXPRESSION LITERAL, 다른 변수, 연산자나 함수를 포함하는 표현식

 

PL/SQL에서 변수를 선언할 때 사용되는 자료형은 SQL에서 사용하던 자료형과 거의 유사

상수명 CONSTANT 데이터 타입 := 상수값;

IDENTIFIER := EXPRESSION;
DECLARE
	VAL_NUM NUMBER;
BEGIN
	VAL_NUM := 100;
    DBMS_OUTPUT.PUT_LINE(VAL_NUM);	--DBMS_OUTPUT: 패키지, PUT_LINE: 프로시저
END;
/

2] 스칼라 변수 / 레퍼런스 변수 : PL/ SQL에서 변수를 선언하기 위해 사용할 수 있는 데이터 형

 

스칼라: SQL에서의 자료형 지정과 거의 동일

--변수 자료형
VEMPLOYEE_ID NUMBER(6);
VFIRST_NAME VARCHAR2(20);

 

레퍼런스: %TYPE 속성과 %ROWTYPE 속성 사용, 이전에 선언된 다른 변수 또는 데이터베이스의 칼럼에 맞추어 변수를 선언하기 위해 %TYPE 속성을 사용

 

--변수 테이블. 컬럼(자료형 참조)%TYPE
VEMPLOYEE_ID EMPLOYEES.EMPLOYEE_ID%TYPE;
VFIRST_NAME EMPLOYEES.FIRST_NAME%TYPE;

%TYPE 속성을 사용하여 선언한 VEMPLOYEE_ID 변수는 EMPLOYEES 테이블의 EMPLOYEE_ID 칼럼의 자료형과 크기를 그대로 참조해서 정의

 

%ROWTYPE은 로우 단위로 참조(레코드 하나)

VEMPLOYEES EMPLOYEES%ROWTYPE;

 

%ROWTYPE의 장점: 칼럼의 개수와 데이터 형식을 모르더라도 지정 가능, SELECT 문장으로 로우 검색할 때 유리

 

3]PL/SQL에서 SQL 문장

PL/SQL의 SELECT 문은 INTO 절이 필요한데, INTO절에 데이터를 저장할 변수를 기술

SELECT절에 있는 칼럼은 INTO 절에 있는 변수와 1대1 대응을 하기에 개수와 데이터형, 길이가 일치하여야한다.

SELECT SELECT_LIST
INTO {VARIABLE_NAME1 [,VARIABLE_NAME2,...] |RECORD_NAME}
FROM TABLE_NAME
WHERE CONDITION;

 

 구문 설명
SELECT_LIST 열의 목록이며 행 함수, 그룹 함수, 표현식을 기술할 수 있다.
VARIABLE_NAME 읽어들인 값을 저장하기 위한 스칼라 변수
RECORD_NAME 읽어 들인 값을 저장하기 위한 PL/SQL RECORD 변수
CONDITION PL/SQL 변수와 상수를 포함하여 열명, 표현식, 상수, 비교 연산자로 구성되며 오직 하나의 값을 RETURN할 수 있는 조건이어야 한다.

 

4] 전체 레코드를 참조하기 위해서는 %ROWTYPE으로 선언

 

DECLARE 
    --레코드로 변수 선언
    VEMPLOYEES EMPLOYEES%ROWTYPE;
BEGIN
    --Lisa 사원의 정보를 레퍼런스 변수에 저장
    SELECT *
    INTO VEMPLOYEES
    FROM EMPLOYEES
    WHERE FIRST_NAME = 'Lisa';
    
    --레코드 변수에 저장된 사원 정보를 출력
    DBMS_OUTPUT.PUT_LINE('사원번호 : ' || TO_CHAR (VEMPLOYEES.EMPLOYEE_ID));
    DBMS_OUTPUT.PUT_LINE('이 름 : ' ||VEMPLOYEES.FIRST_NAME);
    DBMS_OUTPUT.PUT_LINE('급 여 : ' ||VEMPLOYEES.SALARY);
    DBMS_OUTPUT.PUT_LINE('입사일자 : ' || TO_CHAR(VEMPLOYEES.HIRE_DATE, 'YYYY-MM-DD'));
    DBMS_OUTPUT.PUT_LINE('부서번호 : ' || VEMPLOYEES.DEPARTMENT_ID);
END;
/

 

--예제 EMPLOYEES 테이블에 등록된 총 사원의 수와 급여의 합, 급여의 평균을 변수에 대입하여 출력
DECLARE
    VCNT NUMBER;
    VSUM NUMBER;
    VAVG NUMBER(10,2);
BEGIN
    SELECT COUNT(*), SUM(SALARY), AVG(SALARY) INTO VCNT, VSUM, VAVG
    FROM EMPLOYEES;
    
    DBMS_OUTPUT.PUT_LINE('총사원의 수 : ' || VCNT);
    DBMS_OUTPUT.PUT_LINE('급여의 합 : ' || VSUM);
    DBMS_OUTPUT.PUT_LINE('급여의 평균 : ' ||VAVG);
END;
/
--예제 Jack 사원의 직무, 급여, 입사일자, 부서명을 변수에 대입하여 출력
DECLARE
    VEMPLOYEES EMPLOYEES%ROWTYPE;
    VDEPARTMENTS DEPARTMENTS%ROWTYPE;
BEGIN
    SELECT JOB_ID, SALARY, HIRE_DATE, DEPARTMENT_NAME
    INTO VEMPLOYEES.JOB_ID, VEMPLOYEES.SALARY, VEMPLOYEES.HIRE_DATE, VDEPARTMENTS.DEPARTMENT_NAME
    FROM EMPLOYEES EMP INNER JOIN DEPARTMENTS DEPT
    ON EMP.DEPARTMENT_ID = DEPT.DEPARTMENT_ID
    WHERE FIRST_NAME='Jack';
    
    DBMS_OUTPUT.PUT_LINE('직무 : ' || VEMPLOYEES.JOB_ID);
    DBMS_OUTPUT.PUT_LINE('급여 : ' || VEMPLOYEES.SALARY);
    DBMS_OUTPUT.PUT_LINE('입사일자 : ' || TO_CHAR( VEMPLOYEES.HIRE_DATE, 'YYYY-MM-DD'));
    DBMS_OUTPUT.PUT_LINE('부서명 : ' || VDEPARTMENTS.DEPARTMENT_NAME);
END;
/

 

--사원 테이블 (EMPLOYEES01)에서 사원번호가 제인 큰 사원을 찾아낸 뒤 ,
--이 번호 +3번으로 아래의 사원을 사원테이블에 신규 입력하는 
--PL/SQL을 만들어 보자

--복사 테이블 생성
CREATE TABLE EMPLOYEES01
AS
SELECT * FROM EMPLOYEES;

DECLARE
    MAX_EMPLOYEE_ID EMPLOYEES01.EMPLOYEE_ID%TYPE;
BEGIN
    SELECT MAX(EMPLOYEE_ID) INTO MAX_EMPLOYEE_ID FROM EMPLOYEES01;
    
    INSERT INTO EMPLOYEES01 (EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, SALARY, HIRE_DATE,
                            MANAGER_ID, JOB_ID, DEPARTMENT_ID)
    VALUES (MAX_EMPLOYEE_ID +3, 'Olivia', 'Gee', 'Spring', 2800, SYSDATE, 100, 'PR_REP', 20);
    
    COMMIT;
END;
/
SELECT * FROM EMPLOYEES01;

 

3) 제어문: 조건에 의해 분기하는 선택문과 반복된 문장을 한번 기술하고도 여러변 수행하도록 하는 반복문이 있다.

 

1] IF ~ THEN ~ END IF: 특정 조건을 만족하면 처리를 하고, 그렇지 않으면 아무런 처리X

IF 조건문 THEN
	조건처리;
END IF;

 

2] IF ~ THEN ~ ELSE ~ END IF: 조건을 만족할 때의 처리와 그렇지 않을 때의 처리, 즉 두 가지 처리문 중에서 한개를 선택해야 할 때 사용

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

 

DECLARE
    --%ROWRYPE 속성으로 로우를 저장할 수 있는 레퍼런스 변수 선언
    VEMPLOYEES EMPLOYEES%ROWTYPE;
    VSALARY NUMBER(8,2);
BEGIN
    DBMS_OUTPUT.PUT_LINE('사번 / 이름 / 급여');
    DBMS_OUTPUT.PUT_LINE('---------------------------------------');
    --Jack 사원의 전체 정보를 로우 단위로 얻어와 VEMPLOYEES에 저장
    SELECT * INTO VEMPLOYEES
    FROM EMPLOYEES
    WHERE FIRST_NAME ='Jack';
    --커미션이 NULL일 경우 급여만
    IF (VEMPLOYEES.COMMISSION_PCT IS NULL) THEN --커미션이 NULL이면
        VSALARY := VEMPLOYEES.SALARY;
    ELSE    --커미션이 NULL이 아니면 급여+수당
        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 조건문1 THEN
	조건처리 1;
ELSIF 조건문2 THEN
	조건처리 2;
ELSIF 조건문3 THEN
	조건처리 3;
ELSE
	조건처리N;
END IF;

 

DBMS RANDOM.VALUE

랜덤한 숫자를 생성

형식: DBMS_RANDOM.VALUE(최소 범위의 숫자, 최대 범위의 숫자)

 

--소수점 3번 째 자리까지 나타냄
SELECT ROUND(DBMS_RANDOM.VALUE(1,5),3) FROM DUAL;

SELECT ROUND(DBMS_RANDOM.VALUE(10,270),-1) FROM DUAL;

 

DBMS_RANDOM.STRING

랜덤한 문자열 생성

형식: DBMS_RANDOM.STRING(옵션문자, 길이수)

 

-옵션문자

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

 

DECLARE
    VSALARY NUMBER := 0;
    VDEPARTMENT_ID NUMBER := 0;
BEGIN
    SELECT ROUND(DBMS_RANDOM.VALUE(10, 270), -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		--데이터 발견, 존재 X
    DBMS_OUTPUT.PUT_LINE(VDEPARTMENT_ID || '부서에 해당 사원이 없습니다.');
END;
/

 


JDBC(Java DataBase Connectivity): java.sql, javax.sql로 구성

자바 프로그램에서 데이터베이스와 연결하여 데이터베이스 관련 작업을 할 수 있게 해주는 API, 다양한 종류의 관계형 데이터베이스에 접근할 때 사용되는 자바 표준 SQL 인터페이스

 

JDBC는 다음과 같은 데이터베이스 기능을 지원하기 위한 표준 API를 제공

  • 데이터베이스를 연결하여 테이블 형태의 자료를 참조
  • SQL 문을 질의
  • SQL 문의 결과를 처리

각 DBMS와 관령하여 회사도 많고 그로 인해 사용하는 방법이 달라지면 X >> 이러한 문제를 해결하기 위해 SUN은 표준이 되는 인터페이스 제공

 

데이터베이스를 만드는 회사는 SUN사에서 JDBC인터페이스를 통해서 자신들의 데이터베이스에 맞게 기능들을 구현하는 것, 인터페이스만 알면 데이터베이스 조작 가능

 

JDBC드라이버(자료): 데이터베이스 회사들이 SUN사의 표준이 되는 인터페이스를 상속받아 구현해 놓은 것, 해당 DBMS에서 JDBC 관련 API 호출이 가능하도록 관련 인터페이스와 클래스를 구현한 클래스 라이브러리

JDBC는 SQL문을 DBMS에 전달하고 결과 셋을 반환해 주는 중개자 역할을 담당, 결과로 받은 데이터를 자바에서 사용할 수 있는 형태로 변환하여 프로그램에 반환

DBMS: 질의문을 컴파일하여 요청한 작업을 처리

java-컴파일->.class -->배표시 class 파일만 압축파일: .jar

 

JDBC: 자바에서 데이터베이스에 접근할 수 있게 해주는 PROGRAMMING API

THIN DRIVER: 확장, 배포 용이 WEB 적합

 

데이터베이스 인터페이스 사용하기 위해

프로젝트 우클릭, properties, javabuild path, add external jars

 

관계형 데이터베이스는 데이터를 여러 개의 테이블에 나누어서 저장

결과 집합(ResultSet): 쿼리의 조건을 만족하는 레코드들의 집합

커서(cursor): 특정 SQL 문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터

 

JDBC를 이용하여 데이터베이스에 데이터를 액세스하기 위해서는 기본적인 순서

1.java.sql.*;

JDBC API를 사용하기 위해서는 반드시 선언

2.JDBC 드라이버 로딩 및 레지스터 등록

Class.forName() 사용

3.데이터베이스 연결(Connection 객체 얻는다.)

DriverManager.getConnnection() 사용

4.SQL을 위한 Statement 객체 생성

Connection.createStatement() 사용

5.SQL 실행

executeQuery() / executeUpdate()/ execute() 사용

6.ResultSet 결과셋 얻기

SQL문의 실행 결과셋 얻기.ResultSet에 저장된 데이터 값 추력

7.객체 자원 반납(연결 해제)

close() 사용

 

예외처리

-비체크 예외(runtime, nullpoint,...exception)

-체크 예외(반드시 예외처리) : 입출력

1.파일 입출력

2.네트워크 입출력

3.데이터베이스 입출력

 

JDBC관련 기본 클래스

패키지 인터페이스(클래스) 클래스 용도 이용 메소드
java.lang 클래스
Class
지정된 JDBC 드라이버를 실행시간동안 메모리에 로드 forName();
java.sql 클래스
DriverManager
여러 JDBC 드라이버를 관리하는 클래스로 데이터베이스를 접속하여 연결 객체 반환 getConnection();
인터페이스
Connection
특정한 데이터베이스 연결 상태를 표현하는 클래스로 질의할 문장 객체 반환 createStatement();
close();
인터페이스
Statement
데이터베이스에 SQL 질의 문장을 질의하여 그 결과집합 객체를 반환 executeQuery();
close();
인터페이스
ResultSet
질의 결과의 자료를 저장하며 테이블 구조 next(); getString(); getInt();
close();

 

데이터베이스에 연결하기 위해서는 2가지 과정이 필요하다.

가장 먼저 드라이버 클래스를 로딩, DB와 접속을 시도

 

DriverManager 클래스는 Class.forName() 메소드를 통해서 생성

드라이버 클래스들은 로드될 때 자신의 인스턴스(객체)를 생성하고, 자동적으로 DriverManager 클래스는 메소드를 호출하여 그 인스턴스를 등록

 

드라이버 클래스를 찾지 못할 경우 forName() 메소드는 ClassNotFoundException 예외를 발생시키므로 반드시 예외 처리

 

DriverManager: 데이터 원본에 JDBC드라이버를 통하여 커넥션을 만드는 역할, 데이터베이스 연결에 관한 책임을 가지고 있는 객체, Class.forName() 사용하고자 하는 JDBC 드라이버를 지정하여 해당 드라이버 내부에 있는 클래스들을 메모리에 로드하며 반드시 예외 처리를 해야함.

 

Connection: DB의 연결 정보를 담은 객체, 특정 데이터 원본과 연결된 커넥션을 나타낸다. 직접 객체 생성이 불가능하고 getConnection() 메소드를 사용하여 객체 생성 Statement 객체를 생성할 때도 Connection 객체를 사용하여 createStatement() 메소드를 호출하여 생성, SQL 문장을 실행시키기 전에 우선 Connection 객체가 있어야 함.

 

[형식 1]

1-1.Class.forName("드라이버 클래스명")

      Class.forName("oracle.jdbc.driver.OracleDriver") 또는

      Class.forName("oracle.jdbc.OracleDriver")

 

1-2.DriverManager.registerDriver(

                                new orcle.jdbc.driver.OracleDriver());

 

1-3. Connection conn = DriverManager.getConnection(

                                     "연결 url", "사용자명", "password");

 

 

JDBC 드라이버 로딩 & Connection 객체 생성

[형식 1]

Class.forName("oracle.jdbc.driver.OracleDriver"); 또는

Class.forName("oracle.jdbc.OracleDriver");

 

<javaproject 우클릭, properties, javabuilepath, classpath, ojdbc8.jar>

Statement

Connection 객체를 통해 DB에 SQL문을 전달하여 실행 시키고 결과 값을 반환받는 역할을 하는 객체

Connection 클래스의 createStatement() 메소드를 호출하여 얻어지며 생성된 Statement 객체로 질의 문장을 String객체에 담아 인자로 전달하여 executeQuery() 메소드를 호출하여 SQL질의 수행

 

executeUpdate(String sql) - SQL문이 insert, update, delete문 등일 경우

Statement stmt = conn.createStatement();

StringBuffer sb = new StringBuffer();
sb.append("UPDATE employees SET hire_date = sysdate ");
sb.append(" WHERE employee_id = 100");	//where절 앞에 공백
int updateCount = stmt.executeUpdate(sb.toString());

int executeUpdate(String sql) 사용시   //입력, 수정, 삭제

  • executeUpdate() 메소드의 매개변수의 자료형은 String이다.   //반환형 String
  • 문자열, 날짜형 데이터 싱클쿼테이변(')으로 표현해야 한다.
  • 데이터는 대소문자를 구분한다.

 

executeQuery(String sql) - SQL문이 select일 경우

Statement s = conn.createStatement();
String sql = "SELECT employee_id, first_name FROM employees";
ResultSet rs = s.executeQuery(sql);

Statement stmt = conn.createStatement();
StringBuffer sb = new StringBuffer();
sb.append("SELECT employee_id, first_name);
sb.append("FROM employees ");
ResultSet rs = stmt.executeQuery(sb.toString());

 

문자열 결합 연산자 +

-원본 문자열이 변경되지 않으니 문자열을 수정할 때마다 메모리에 새로운 문자열이 생성된고, 이전 문자열은 메모리에 남아 쓸데없는 자리만 차지하게 된다.

 

StringBuffer, StringBuilder

-StringBuffer 객체에 저장된 문자열은 수정할 수 있다.

-String 객체와 다르게 StringBuffer 객체는 +연산자를 통해 매번 새로운 String 객체를 생성하지 않고, append() 메서드를 통해 String 객체 하나만으로도 문자열을 다룰 수 있다.

-버퍼(buffer: 데이터를 임시로 저장하는 메모리)에 문자열 저장

-버퍼 내부에서 추가, 수정, 삭제 작업 가능

 

결과 집합(ResultSet)에서 레코드에 하나씩 접근하여서 작업을 하여야 한다. executeQuery() 메소드에 의하여 반환된 ResultSet 객체에는 SELECT문장에 의하여 추출된 모든 레코드가 들어 있다. 하지만 한 번에 하나의 레코드만 접근할 수 있다. 이것을 위하여 커서(특정 sql 문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터 )라는 포인터가 제공되는데 이 커서를 움직이는 다양한 메소드가 제공

 

메소드 설명
close() 결과 집합은 닫는다.
first() 커서를 처음 레코드로 옮긴다.
last() 커서를 마지막 레코드로 옮긴다.
getRow() 현재 레코드 번호를 얻는다.
next() 다음 레코드로 이동한다.
previous() 이전 레코드로 이동한다.
absolute(int row) 지정된 row로 커서를 이동한다.
isFirst 첫 레코드이면 true 반환
isLast() 마지막 레코드이면 true 반환

 

메소드의 매개변수로 칼럼명으로 접근할 수 있고, 쿼리문 작성시 컬럼 순번으로 접근할 수 있다.

 

Statement stmt = conn.createStatement();
StringBuffer sb = new StringBuffer();
sb.append("SELECT employee_id, first_name ");
sb.append("FROM employees ");
ResultSet rs = stmt.executeQuery(sb.toString());

int empno = rs.getInt("employee_id");
String ename = rs.getString("first_name");

int empno = rs.getInt(1);
String ename = rs.getString(2);

 

자바에서는 인덱스 번호가 0부터 시작하지만 SQL에서는 1부터 시작한다.

결과 집합 처리 시 체크 사항

  • rs.next()를 맨 처음 한번 반드시 실행하여야 한다. 결과를 얻은 객체의 가장 처음 로우에 커서를 옮기는 작업으로 생각하면 된다. 만약 결과가 없다면 false를 리턴
  • ResultSet 객체에 next()를 호출함으로써 해당 객체는 getXXX() 메소드를 호출할 준비를 하게된다.
  • getInt(), getString(), getDate() 등 여러가지 데이터 형에 대한 메소드가 존재
  • 자바의 인덱스의 시작은 0부터이지만, 데이터베이스는 1부터 시작한다.

결과 집합에서 이동: 한 레코드씩 처리, 다음 행으로 이동시 next() 메소드를 사용

ResultSet 반환

BOF(Begin Of File, Before the First Row): 질의 결과 처음 커서 위치

EOF(End Of File, After the Last Row)

 

ResultSet: SELECT문을 사용한 질의 성공 시 ResultSet 반환

 

JDBC 코딩 절차

Driver 등록 - DBMS 연결 - Statement 생성 - SQL 전송 - 결과 받기 - 닫기(객체반환)

Statement method를 이용하여 SQL문 실행, 실행결과를 ResultSet(Select) 혹은 int형 변수(DML)로 받아서 처리

String query = "UPDATE subject SET s_name = '전기전자학과' WHERE s_num = '03'";
int result = stmt.executeUpdate(query);