CallableStatement
JDBC, PROCEDURE 연동
프로시저를 호출하는 객체 => CallableStatement객체
테스트 하기 위해서 먼저 DB에서 memo테이블에 글을 등록하는 프로시저를 작성
--작성자, 메모내용을 인파라미터로 받아 MEMO테이블에 INSERT하는 프로시저 작성
CREATE OR REPLACE PROCEDURE MEMO_ADD
(PNAME IN MEMO.NAME%TYPE, PMSG IN MEMO.MSG%TYPE)
IS
BEGIN
INSERT INTO MEMO(IDX,NAME,MSG,WDATE)
VALUES(MEMO_SEQ.NEXTVAL,PNAME,PMSG,SYSDATE);
END;
/
JDBC로 PROCEDURE 실행
package jdbc.day04;
import java.sql.*;
import jdbc.util.DBUtil;
public class CallableStatementTest {
public static void main(String[] args) throws Exception
{
if(args.length!=2) {
System.out.println("명령줄 인수 2개를 입력하세요");
return;
}
Connection con=DBUtil.getCon();
//in parameter가 있을 경우
String sql="{call MEMO_ADD(?,?)}";
CallableStatement cstmt = con.prepareCall(sql);
cstmt.setString(1, args[0]);
cstmt.setString(2, args[1]);
boolean b=cstmt.execute();
cstmt.close();
con.close();
}
}
--메모 글번호를 인파라미터로 받아 해당 글을 삭제하는 프로시저를 작성 후
자바에서 삭제할 글의 글번호를 Scanner로 입력받아 삭제
PROCEDURE
CREATE OR REPLACE PROCEDURE MEMO_DELETE(PIDX IN MEMO.IDX%TYPE)
IS
BEGIN
DELETE FROM MEMO WHERE IDX=PIDX;
END;
/
JAVA
package jdbc.day04;
import java.sql.*;
import java.util.Scanner;
import jdbc.util.DBUtil;
public class CSTMT {
public static void main(String[] args) throws Exception{
Scanner sc= new Scanner(System.in);
System.out.println("삭제할 글 번호");
int idx = sc.nextInt();
Connection con=DBUtil.getCon();
String sql="{call MEMO_DELETE(?)}";
CallableStatement cstmt = con.prepareCall(sql);
cstmt.setInt(1, idx);
boolean b = cstmt.execute();
if(b==false) {
System.out.println("없음");
}else {
System.out.println("성공");
}
cstmt.close();
con.close();
}
}
--부서번호를 인파라티터로 받아들여 해당 부서의 사번, 사원명, 부서번호, 부서명, 업무, 근무지를
가져오는 프로시저를 작성 후 자바와 연동해보자
PROCEDURE
CREATE OR REPLACE PROCEDURE EMP_LIST
(PDNO IN NUMBER, EMPCR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN empcr for
select empno, ename, d.deptno, dname, job, loc
from emp e join dept d
on e.deptno=d.deptno and e.deptno=pdno;
END;
/
JAVA
package jdbc.day04;
import java.sql.*;
import jdbc.util.DBUtil;
public class CSTMT2 {
public static void main(String[] args) throws Exception
{
if(args.length!=1) {
System.out.println("명령줄 인수로 부서번호를 입력");
return;
}
Connection con = DBUtil.getCon();
String sql="{call EMP_LIST(?,?)}";
CallableStatement cstmt = con.prepareCall(sql);
//1. 인파라미터 셋팅
cstmt.setInt(1, Integer.parseInt(args[0]));
//2. 아웃파라미터 등록
cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
cstmt.execute();//프로시저 호출 실행
ResultSet rs = (ResultSet)cstmt.getObject(2);
while(rs.next()) {
int empno=rs.getInt("empno");
String ename=rs.getString("ename");
String job = rs.getString("job");
int deptno =rs.getInt("deptno");
String dname = rs.getString("dname");
String loc = rs.getString("loc");
System.out.println(empno+" "+ename+" "+job+" "+deptno+" "+dname+" "+loc);
}
rs.close();
cstmt.close();
con.close();
}
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
NetBeans
UI를 DRAG AND DROP 형식으로 만들면 Source Code가 작성된다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
SQL PACKAGE
- 패키지는 오라클 데이터베이스에 저장되어 있는 서로 관련있는 PL/SQL 프로시져와 함수들의 집합
- 패키지는 선언부와 본문 두 부분으로 나누어진다.
--패키지 선언
CREATE OR REPLACE PACKAGE MYEMP AS
PROCEDURE allEmp;
PROCEDURE allSal;
END MYEMP;
/
--패키지 바디 구성
CREATE OR REPLACE PACKAGE BODY MYEMP AS
PROCEDURE allEmp
IS
CURSOR empCr is
SELECT empno, ename, job from emp order by 1 asc;
BEGIN
FOR K IN empCr LOOP
DBMS_OUTPUT.PUT_LINE('사번: '||K.empno);
DBMS_OUTPUT.PUT_LINE('사원명: '||K.ename);
DBMS_OUTPUT.PUT_LINE('사번: '||K.job);
END LOOP;
END allEmp;
PROCEDURE allSal
IS
BEGIN
--평균 급여, 최대급여, 최소급여 업무별
for k in (select job, round(avg(sal),2) av, max(sal) mx, min(sal) mn from emp group by job) loop
dbms_output.put_line(k.job||' '||k.av||' '||k.mx||' '||k.mn);
end loop;
END allSal;
END MYEMP;
/
set serveroutput on
execute myemp.allemp;
execute myemp.allsal;
Trigger
- 트리거란 INSERT, UPDATE, DELETE문이 TABLE에 대해 행해질 때 묵시적으로 수행되는 PROCEDURE이다.
- Tirgger는 TABLE과는 별도로 DATABASE에 저장된다.
- Trigger는 VIEW에 대해서가 아니라 TABLE에 관해서만 정의할 수 있다.
--구문----------------------------------------
create [or replace] trigger triger_name
{BEFORE | AFTER} trigger_event [OF column1,...]
ON table_name
[FOR EACH ROW [WHEN trigger_condition]]
trigger_body;
--DEPT테이블이 수정될 때 로그 기록을 남기는 트리거
CREATE OR REPLACE TRIGGER TRG_TEST
BEFORE UPDATE ON DEPT
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('변경 전 컬럼값: '||:OLD.DNAME);
DBMS_OUTPUT.PUT_LINE('변경 전 컬럼값: '||:NEW.DNAME);
END;
/
UPDATE DEPT SET DNAME='회계부서' WHERE DEPTNO=20;
rollback;
--트리거 실습
1) 입고 테이블에 상품이 입고될 경우 상품 테이블의 상품 보유 수량이 자동으로 변경
2) 입고 테이블의 상품 수량을 수정하면 상품 테이블의 수량도 자동으로 조절되도록 트리거를 작성
CREATE TABLE 상품(
PCODE VARCHAR2(10) PRIMARY KEY, --상품코드
PNAME VARCHAR2(20) NOT NULL, --상품명
PCOMPANY VARCHAR2(20), --제조사
PRICE NUMBER(8), --가격
PQTY NUMBER(6) DEFAULT 0 --보유 수량
);
CREATE SEQUENCE 상품_SEQ
START WITH 1
INCREMENT BY 1
NOCACHE;
INSERT INTO 상품
VALUES('A'||상품_SEQ.NEXTVAL,'키보드','삼성',130000,20);
INSERT INTO 상품
VALUES('A'||상품_SEQ.NEXTVAL,'오토바이','BMW',1300000,10);
commit;
CREATE TABLE 입고(
IDX NUMBER(5) PRIMARY KEY, --입고번호
PCODE_FK VARCHAR2(10) REFERENCES 상품(PCODE), --상품코드
INDATE DATE DEFAULT SYSDATE, --입고일
IQTY NUMBER(6), --입고 수량
IPRICE NUMBER(8) --입고가
);
CREATE SEQUENCE 입고_SEQ
START WITH 1
INCREMENT BY 1
NOCACHE;
--입고 테이블에 상품이 입고될 경우 상품 테이블의 상품 보유 수량이 자동으로 변경
CREATE OR REPLACE TRIGGER MYTRG
AFTER INSERT ON 입고
FOR EACH ROW
BEGIN
UPDATE 상품 SET PQTY=PQTY+:NEW.IQTY WHERE PCODE=:NEW.PCODE_FK;
DBMS_OUTPUT.PUT_LINE(:NEW.PCODE_FK||' '||:NEW.IQTY);
END;
/
select * from 상품;
select * from 입고;
INSERT INTO 입고(IDX,PCODE_FK,IQTY,IPRICE)
VALUES(입고_SEQ.NEXTVAL,'A2',5,120000);
--입고 테이블의 상품 수량을 수정하면 상품 테이블의 수량도 자동으로 조절되도록 트리거를 작성
CREATE OR REPLACE TRIGGER MYTRG2
AFTER UPDATE ON 입고
FOR EACH ROW
BEGIN
UPDATE 상품 SET PQTY=PQTY-(:OLD.IQTY-:NEW.IQTY) WHERE PCODE=:NEW.PCODE_FK;
DBMS_OUTPUT.PUT_LINE(:NEW.PCODE_FK||' '||:NEW.IQTY);
END;
/
--트리거 삭제
DROP TRIGGER MYTRG
--트리거 비활성화 / 활성화
ALTER TRIGGER MYTRG DISABLE
ALTER TRIGGER MYTRG ENABLE
--트리거 데이터 사전 조회
SELECT * FROM USER_TRIGGERS WHERE TRIGGER_NAME='MYTRG';
'개발자 > 국비지원 SW' 카테고리의 다른 글
국비지원 39일차 - javascript 참조유형, function, 전역변수, 지역변수, 연산자 (0) | 2020.06.09 |
---|---|
국비지원 38일차 - NetBean, JavaScript, 자료형 (0) | 2020.06.08 |
국비지원 36일차 - PreparedStatement, MVC패턴 사원관리 프로그램, CURSOR, 암시적 CURSOR, PL/SQL 오류의 종류, function (0) | 2020.06.04 |
국비지원 35일차 - JDBC INSERT, UPDATE, SELECT ,PL/SQL 테이블 타입, 레코드 타입 (0) | 2020.06.03 |
국비지원 34일차 - LCD, PIEZO, JDBC, PL/SQL, DECLARE, 반복문, EXIT조건 (0) | 2020.06.02 |