패키지는 업무와 관련된 Stored Procedure 및 Stored Function을 관리하고, 이를 패키지 단위로 배포할 때 유용하게 사용된다. 패키지는 선언부와 본문으로 구분된다. 선언부는 패키지에 포함될 Stored Procedure 또는 Stored Function을 포함한다.
CREATE OR REPLACE PACKAGE employee_pkg AS
PROCEDURE print_ename(p_empno NUMBER);
PROCEDURE print_sal(p_empno NUMBER);
END employee_pkg;
CREATE OR REPLACE PACKAGE BODY employee_pkg AS
PROCEDURE print_ename(p_empno NUMBER) IS
e_name emp.ename%TYPE;
BEGIN
SELECT ename
INTO e_name
FROM emp
WHERE empno = p_empno;
DBMS_OUTPUT.PUT_LINE(e_name);
EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Invalid Employee Number');
END print_ename;
PROCEDURE print_sal(p_empno NUMBER) IS
e_sal emp.sal%TYPE;
BEGIN
SELECT sal
INTO e_sal
FROM emp
WHERE empno = p_empno;
DBMS_OUTPUT.PUT_LINE(e_sal);
EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Invalid Employee Number');
END print_sal;
END employee_pkg;
실행
EXEC EMPLOYEE_PKG.PRINT_ENAME(7369); -- 실행값 : SMITH
EXEC EMPLOYEE_PKG.PRINT_SAL(7369); -- 실행값 : 800
EXEC EMPLOYEE_PKG.PRINT_ENAME(8000); -- 실행값 : 예외 발생으로 'Invalid Employee Number' 출력
트리거는 데이터의 변경(INSERT, DELETE, UPDATE)문이 실행될 때 자동으로 같이 실행되는 프로시저를 말한다.
오라클은 기본적으로 실행 전(BEFORE)과 실행 후(AFTER) 트리거를 지원한다.
CREATE OR REPLACE TRIGGER print_message
AFTER INSERT ON dept
BEGIN
DBMS_OUTPUT.PUT_LINE('dept 테이블에 정상적으로 데이터가 추가되었습니다.');
END;
트리거를 생성한 후 dept 테이블에 데이터를 추가하면 등록된 트리거가 동작하면서
'dept 테이블에 정상적으로 데이터가 추가되었습니다'를 출력한다.
INSERT INTO dept VALUES (70,'EDUCATION' , 'JEJU');
COMMIT; -- DBMS에 해당 문구가 출력된다
FOR EACH ROW: 매번 추가되는 행의 수만큼 TRIGGER가 발생하도록 하는 함수
:new.컬럼이름 : 추가, 수정할 때 해당 컬럼의 새로운 값을 저장한다.
CREATE OR REPLACE TRIGGER afterinsertbook
AFTER INSERT ON book FOR EACH ROW
BEGIN
INSERT INTO book_log
VALUES(:new.bookid, :new.bookname, :new.publisher, :new.price);
COMMIT;
DBMS_OUTPUT.PUT_LINE('삽입한 데이터를 book_log 테이블에 백업했습니다');
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END;
JDBC
JDBC란 자바를 이용하여 데이터베이스에 접근하여 각종 SQL 문을 수행할 수 있도록 제공하는 API를 말한다.
JDBC의 구조와 역할
JDBC는 크게 JDBC 인터페이스와 JDBC 드라이버로 구성되어 있다.

JDBC 드라이버 종류
JDBC 드라이버는 DBMS의 벤더나 다른 연구 단체들에서 만들어진다.
JDBC를 이용한 데이터베이스 연결 방법
1 단계 : 드라이버를 로드 한다.
2 단계 : Connection 객체를 생성한다.
3 단계 : Statement 객체를 생성한다.
4 단계 : SQL문에 결과물이 있다면 ResultSet 객체를 생성한다.
5 단계 : 모든 객체를 닫는다.
public class DriverMain {
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.OracleDriver");
System.out.println("오라클 드라이버가 정상적으로 로드되었습니다.");
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
}
import java.sql.*;
public class ConnectionMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
try {
//JDBC 수행 1단계 : 드라이버 로드
Class.forName(db_driver);
//JDBC 수행 2단계 : connection 객체 생성 (오라클 접속을 위한 인증)
Connection conn = DriverManager.getConnection(db_url,db_id,db_password);
System.out.println("Connection 객체가 생성되었습니다.");
}catch(SQLException e) {
e.printStackTrace();
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
}
package kr.s31.jdbcstatement;
import java.sql.*;
public class CreateTableMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
String sql = null;
try {
// JDBC 수행 1단계 : DriverLoad
Class.forName(db_driver);
//JDBC 수행 2단계 :Connection 객체 생성(오라클 접속을 위한 인증)
conn = DriverManager.getConnection(db_url, db_id, db_password);
System.out.println("test1 테이블을 생성합니다.");
sql = "CREATE TABLE test1 (id VARCHAR2(10) , age NUMBER)";
/*
* 테이블을 생성하는 SQL 문
* 접속한 계정에 테이블명이 중복되면 에러가 발생하기 때문에
* 동일 계정에서는 한 번만 수행함
*/
//JDBC 수행 3단계 : Statement 객체 생성
stmt = conn.createStatement() ;
//JDBC 수행 4단계 : SQL문을 실행해서 DB에 table 생성
stmt.executeUpdate(sql);
System.out.println("테이블이 정상적으로 생성되었습니다.");
}catch(SQLException e) {
e.printStackTrace();
}catch(ClassNotFoundException e) {
e.printStackTrace();
} finally {
//자원 정리
if (stmt != null) try {stmt.close();} catch(SQLException e) { }
if(conn !=null) try {conn.close() ;} catch(SQLException e) { }
}
}
}
package kr.s31.jdbcstatement;
import java.sql.*;
public class AlterTableMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
String sql = null;
try {
//JDBC 수행 1단계 : 드라이버 로드
Class.forName(db_driver);
//JDBC 수행 2단계 : Connection 객체 생성 (오라클 접속을 위한 인증)
conn = DriverManager.getConnection(db_url, db_id, db_password);
System.out.println("test1 테이블의 컬럼을 수정합니다.");
sql = "ALTER TABLE test1 MODIFY(id VARCHAR2(10) NOT NULL)";
//JDBC 수행 3단계 : Statement 객체 생성
stmt = conn.createStatement();
//JDBC 수행 4단계 : SQL문을 수행해서 테이블에 정보를 변경하는 작업 수행
stmt.executeUpdate(sql);
System.out.println("테이블의 컬럼 정보 수정을 완료하였습니다.");
}catch (Exception e) {
e.printStackTrace();
}
finally {
if (stmt != null) try {stmt.close();} catch(SQLException e) { }
if (conn != null) try {conn.close();} catch(SQLException e) { }
}
}
}
package kr.s31.jdbcstatement;
import java.sql.*;
public class DropTableMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
String sql = null;
try {
//JDBC 수행 1단계 : 드라이버 로드
Class.forName(db_driver);
//JDBC 수행 2단계 : Connection 객체 생성 (오라클 접속을 위한 인증)
conn = DriverManager.getConnection(db_url, db_id, db_password);
System.out.println("test1 테이블을 삭제합니다.");
sql = "DROP TABLE test1";
//JDBC 수행 3단계 : Statement 객체 생성
stmt = conn.createStatement();
//JDBC 수행 4단계 : SQL문을 수행해서 테이블에 정보를 변경하는 작업 수행
stmt.executeUpdate(sql);
System.out.println("테이블 삭제를 완료하였습니다.");
}catch (Exception e) {
e.printStackTrace();
}
finally {
if (stmt != null) try {stmt.close();} catch(SQLException e) { }
if (conn != null) try {conn.close();} catch(SQLException e) { }
}
}
}
CRUD 작업
CCreate (생성) ---> INSERT 문
RRead (읽기) -----> SELECT 문
UUpdate (갱신) --> UPDATE 문
DDelete (삭제) ---> DELETE 문
package kr.s31.jdbcstatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class InsertMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
String sql = null;
try {
//JDBC 수행 1단계 : Driver load
Class.forName(db_driver);
//JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(db_url, db_id, db_password);
//SQL 문 작성
sql = "INSERT INTO test1(id,age) VALUES('SKY',30)" ;
//JDBC 수행 3단계 : Statement 객체 생성
stmt = conn.createStatement() ;
//JDBC 수행 4단계 : SQL문을 실행해서 하나의 행을 삽입
// : 삽입 작업 후 삽입한 행의 개수를 반환
int count = stmt.executeUpdate(sql);
System.out.println(count + "개의 행을 추가했습니다.");
} catch (Exception e) {
e.printStackTrace();
}finally {
if (conn != null) try {conn.close();} catch(SQLException e) {}
if (stmt != null) try {stmt.close();} catch(SQLException e) {}
}
}
}
package kr.s31.jdbcstatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class SelectMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String sql = null;
try {
//JDBC 수행 1단계 : Driver load
Class.forName(db_driver);
//JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(db_url, db_id, db_password);
//SQL 문 작성
sql = "SELECT * FROM test1";
//JDBC 수행 3단계 :Statement 객체 생성
stmt = conn.createStatement();
//JDBC 수행 4단계: SQL문을 실행해서 테이블로부터
// 레코드(행)을 전달받아서 결과 집합을 만들고 RESULT SET객체에 담아서 반환
rs = stmt.executeQuery(sql);
System.out.println("ID\t나이");
//ResultSet에 보관된 결과 집합에 접근하여 행 단위로 데이터 추출
while(rs.next()) {
//컬럼명을 통해서 데이터 반환
/*
System.out.print(rs.getString("id"));
System.out.print("\t");
System.out.println(rs.getInt("age"));
*/
//컬럼 인덱스를 통해서 데이터를 반환
System.out.print(rs.getString(1));
System.out.print("\t");
System.out.println(rs.getInt(2));
}
}catch (Exception e) {
e.printStackTrace();
}finally {
if (rs != null) try {rs.close();} catch(SQLException e) {}
if (stmt != null) try {stmt.close();} catch(SQLException e) {}
}
}
}
package kr.s31.jdbcstatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class UpdateMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
String sql = null;
try {
//JDBC 수행 1단계 : Driver load
Class.forName(db_driver);
//JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(db_url,db_id, db_password);
// SQL문 작성
sql = "UPDATE test1 SET age =90 WHERE id='SKY'";
stmt = conn.createStatement();
//JDBC 수행 4단계 : SQL문을 실행해서 테이블의 행을 수정하고
// 수정한 행의 개수를 반환
int count = stmt.executeUpdate(sql);
System.out.println(count + "개 행의 정보를 수정했습니다.");
} catch (Exception e) {
e.printStackTrace();
}finally {// 자원 정리
if (conn != null) try {conn.close();} catch(SQLException e) {}
if (stmt != null) try {stmt.close();} catch(SQLException e) {}
}
}
}
package kr.s31.jdbcstatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class DeleteMain {
public static void main(String[] args) {
String db_driver = "oracle.jdbc.OracleDriver";
String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
String db_id = "user01";
String db_password = "1234";
Connection conn = null;
Statement stmt = null;
String sql = null;
try {
//JDBC 수행 1단계 : Driver load
Class.forName(db_driver);
//JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(db_url, db_id, db_password);
//SQL문 작성
sql = "DELETE FROM test1 WHERE id='SKY'";
//JDBC 수행 3단계 : Statement 객체 생성
stmt = conn.createStatement();
//JDBC 수행 4단계 : SQL 문을 실행해서 테이블에서 행을 삭제한 후 삭제한
// 행의 개수 반환
int count = stmt.executeUpdate(sql);
System.out.println(count + "개 행을 삭제했습니다.");
}
catch (Exception e) {
e.printStackTrace();
}finally {
if (conn != null) try {conn.close();} catch(SQLException e) {}
if (stmt != null) try {stmt.close();} catch(SQLException e) {}
}
}
}
Test2 테이블 생성
CREATE TABLE test2 (
id VARCHAR2(10) PRIMARY KEY,
name VARCHAR2(30) NOT NULL ,
age NUMBER(3),
rec_date DATE NOT NULL
);
DBUtil 메소드
package kr.util;
import java.sql.Connection;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
public class DBUtil {
private static final String DB_DRIVER = "oracle.jdbc.OracleDriver";
private static final String DB_URl = "jdbc:oracle:thin:@localhost:1521:xe";
private static final String DB_ID = "user01";
private static final String DB_PASSWORD = "1234";
//Connection 객체를 생성해서 반환
public static Connection getConnection() throws ClassNotFoundException, SQLException{
//JDBC 수행 1단계 : 드라이버 로드
Class.forName(DB_DRIVER);
//JDBC 수행 2단계 : Connection 객체 생성
return DriverManager.getConnection(DB_URl,DB_ID,DB_PASSWORD);
}
//자원 정리
public static void executeClose(ResultSet rs, PreparedStatement pstmt, Connection conn) {
if(rs != null) try {rs.close();} catch(SQLException e) {}
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
public static void executeClose(CallableStatement cstmt, Connection conn) {
if(cstmt != null) try {cstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
DBUtil 메소드를 만들었기 때문에 Oracle을 매 파일마다 연결하지 않고 DBUtil을 import만 해줘도 연결이 가능하다.
자원정리 또한 DBUtil에 작성을 했기 때문에 DBUtil에 있는 내용을 불러와주면 된다.
DBUtil 메소드를 받고, SQL문을 작성하여 테이블에 데이터 삽입하기
package kr.s32.jdbc.preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import kr.util.DBUtil;
public class InsertMain {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//JDBC 수행문 1, 2단계
conn = DBUtil.getConnection();
//SQL문 작성 1번? 2번? 3번? 4번SYSDATE => 자리 잡기
sql = "INSERT INTO test2 (id, name, age, reg_date) VALUES(?,?,?,SYSDATE)";
//JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ? 에 데이터를 바인딩
pstmt.setString(1, "wave"); // SQL문의 1번 물음표에 "star" 데이터를 삽입
pstmt.setString(2, "이순신"); // SQL문의 2번 물음표에 "홍길동" 데이터를 삽입
pstmt.setInt(3, 50); //SQL문의 3번 물음표에 20 데이터를 삽입
//JDBC 수행 4단계 : SQL문을 실행해서 테이블에 행을 추가한다.
int count = pstmt.executeUpdate(); // 이미 위에서 SQL을 전달했기 때문에 여기서는 SQL을 전달하면 안 된다.
System.out.println(count + "개 행을 추가했습니다.");
} catch (Exception e) {
e.printStackTrace();
}finally {
//자원 정리
DBUtil.executeClose(null, pstmt, conn);
}
}
}
DBUtil 메소드를 import 받고 Select문을 사용하여 Table을 읽어오기
package kr.s32.jdbc.preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import kr.util.DBUtil;
public class SelectMain {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
ResultSet rs = null;
try {//JDBC 수행문 1, 2단계
conn = DBUtil.getConnection();
//SQL문 작성
sql = "SELECT * FROM test2 ORDER BY reg_date DESC";
//JDBC 수행 3단계 --- SQL문 전달
pstmt = conn.prepareStatement(sql);
//JDBC 수행 4단계 : SQL 문장을 실행해서 테이블에 반영하고
// 결과 집합을 ResultSet에 담아서 반환하기
rs = pstmt.executeQuery();
System.out.println("ID\t이름\t나이\t등록일");
while(rs.next()) {
/*
* System.out.print(rs.getString(1)); System.out.print("\t");
* System.out.print(rs.getString(2)); System.out.print("\t");
* System.out.print(rs.getInt(3)); System.out.print("\t");
* System.out.println(rs.getDate(4));
*/
System.out.print(rs.getString("id"));
System.out.print("\t");
System.out.print(rs.getString("name"));
System.out.print("\t");
System.out.print(rs.getInt("age"));
System.out.print("\t");
//System.out.println(rs.getDate("reg_date")); --> 날짜 까지만 표시
System.out.println(rs.getString("reg_date")); //시:분:초까지 모두 표시
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//자원 정리
DBUtil.executeClose(rs, pstmt, conn);
}
}
}
DBUtil을 import 받고 Update문을 이용하여 테이블의 데이터를 교체시킨다.
package kr.s32.jdbc.preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import kr.util.DBUtil;
public class UpdateMain {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//JDBC 수행문 1,2 단계
conn= DBUtil.getConnection();
//SQL문 작성
sql = "UPDATE test2 SET name=?, age=? WHERE id=?";
//JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터를 바인딩한다
pstmt.setString(1, "강호동");
// 1번의 물음표 NAME에 해당 => 바꿀 이름 입력
pstmt.setInt(2, 40);
// 2번의 물음표 AGE에 해당 => 바꿀 나이 입력
pstmt.setString(3, "sky");
// 3번의 물음표 ID에 해당 => 위치 지정
//JDBC 수행 4단계 : SQL문을 실행해서 테이블의 데이터를 수정한다.
int count = pstmt.executeUpdate();
System.out.println(count + "개 행의 정보를 수정했습니다.");
}
catch (Exception e) {
e.printStackTrace();
}finally {
//자원 정리
DBUtil.executeClose(null, pstmt, conn);
}
}
}