PC

블로그 이미지

DAVID

160624: 71회차

Programming 2016. 6. 24. 16:18

종료하기 전 티스토리 네이버 로그아웃 할 것


1. 툴

동일

추가시: 


2. 폴더

동일

추가시:


3. 사용할 사이트

동일

추가시:


4. 공부하는 것


[08] Trigger

[01] Trigger
 
   - UPDATE, INSERT, DELETE 쿼리가 시행될 때마다 부가적으로 다른 쿼리를 
     실행 할 수 있는 기술입니다.
 
   - 트리거링 사건(Triggering Event)에 의해 자동으로 실행되는 PL-SQL라고 할 수 있습니다.
 
   - 너무 복잡한 트리거의 사용은 DB의 속도를 저하시키는 단점이 있습니다.
 
   - 트리거는 문장 트리거 와 행 트리거로 나눌 수 있습니다. 
 
   - 문장 트리거는 FOR EACH ROW 옵션 절을 사용하지 않고 트리거링 사건에 의해서
      단 한번 실행되며, 컬럼의 데이터값에 상관없이 칼럼에 변화가 일어남을 감지하여
     실행되는 트리거입니다. 
   
   - 행 트리거는 FOR EACH ROW 옵션 절을 사용하고 칼럼의 각 데이터 행에 변화가 
      생길때마다 실행되며 데이터 행의 실제 값을 수정, 변경, 저장시 사용합니다.
 
  
 
1. 트리거의 구성요소
 
   - 트리거 유형: Statement Level, Row Level
 
   - 트리거 타이밍
     . BEFORE: 쿼리가 실행되기 전에 실행하는 트리거
     . AFTER : 쿼리가 실행되고 난후 실행하는 트리거
 
   - 트리거 이벤트: INSERT, UPDATE, DELETE
 
   - 트리거 몸체: PL/SQL 블럭
 
   - 트리거 조건: WHEN 조건
 
 
 
   - 문법
 
     CREATE OR REPLACE TRIGGER 트리거명  BEFORE | AFTER
 
     trigger_evnet   ON   table_name
 
     [FOR EACH ROW]
 
     [WHEN (condition) ]
 
     PL/SQL block
 
 
 
 
2. 문장 레벨의 트리거
 - 전체 transaction 작업에 대해 1번발생되는 트리거로 default 입니다.
 - emp 테이블에 대해서 insert, update, delete가 발생하면 아래의
   트리거가 자동으로 작동되어 요일이 '토, 일'인 경우는 아래처럼
   메시지를 출력합니다.
 
 
 
CREATE or REPLACE TRIGGER t_test1
BEFORE INSERT or UPDATE or DELETE ON emp
BEGIN
IF (to_char(sysdate, 'DY') IN ('토', '일')) or (to_char(sysdate, 'DY') IN ('SAT', 'SUN')) THEN
    DBMS_OUTPUT.PUT_LINE('주말에는 데이터를 변경할 수 없습니다.!!');
ELSE
    DBMS_OUTPUT.PUT_LINE('월요일 ~ 금요일에는 데이터를 변경할 수 있습니다.!!');
END IF;
END;
/
 
 
 
 
 
- 오라클 서버의 날짜를 토요일이나 일요일로 변경해 테스트합니다.
UPDATE emp SET sal = sal * 1.1;
SELECT * FROM emp;
 
 
 
3. 문장 트리거 예제
    
   CREATE TABLE test (
       name VARCHAR2(10),
       d_date VARCHAR2(20)
   );
 
 
    CREATE OR REPLACE TRIGGER  trigger1 AFTER
    UPDATE on EMP
    BEGIN
             INSERT INTO test VALUES('test1', sysdate);
    END;
    /
 
   -- 실행
 
    UPDATE emp SET mgr = 2  ;
         
    SELECT * FROM test;
 
 
 
4.  행 트리거 예제  
    
    CREATE OR REPLACE TRIGGER  trigger2 AFTER
    UPDATE on EMP
    FOR EACH ROW    -- 행 트리거
    BEGIN
             INSERT INTO test VALUES('test2', sysdate);
    END;
    /
 

  --실행 
  DELETE FROM test
        
  UPDATE emp SET mgr = 1; 
         
  SELECT * FROM test;


 

[09] Trigger - 매출액 관리 실습

[01] 날짜별 매출액 관리
 
1. 테이블 구조
 
-- 예매 정보 테이블
DROP TABLE advance_sale PURGE;
 
CREATE TABLE advance_sale(
  NUM     NUMBER                  NOT NULL,   -- 일련번호
  SDATE   VARCHAR2(30 BYTE)   NOT NULL,   -- 예매 날짜
  QTY     NUMBER                   NOT NULL,   -- 수량
  AMOUNT  NUMBER               NOT NULL    -- 금액
);
 
SELECT * FROM advanced_sale; 
 
 
 
-- 총 매출액 테이블
DROP TABLE sales PURGE;
 
CREATE TABLE sales(
  SDATE      VARCHAR2(30 BYTE) NOT NULL, -- 날짜
  DAYAMOUNT  NUMBER            NOT NULL, -- 일단위 총 금액
  DAYQTY     NUMBER            NOT NULL  -- 일단위 총 수량
)
 
SELECT sdate, dayamount, dayqty FROM sales;
 
 
 
 
2. 트리거
 
- advance_sale 테이블에 insert, update, delete 이벤트가 발생하면
   t_sales 트리거를 작동합니다.
- FOR EACH ROW: 행 트리거, 각 행에 대해서 트리거가 발생된다. 
 
CREATE OR REPLACE TRIGGER t_sales
AFTER INSERT OR UPDATE OR DELETE ON advance_sale -- advance_sale 테이블
FOR EACH ROW  -- 각각의 행에 대해서 작동
DECLARE 
    v_cnt NUMBER;
BEGIN  
    -- :new 객체는 추가되는 레코드를 저장하고 있는 객체  
    -- 기존에 등록된 레코드의 날짜와 새로 추가되는 컬럼의 날짜를 비교하여
-- 같은 레코드의 수를 리턴합니다.  
    SELECT count(*) INTO v_cnt FROM sales WHERE sdate = :new.sdate;
 
    IF INSERTING THEN -- advance_sale 테이블에 레코드 추가일경우
        IF v_cnt > 0 THEN 
   -- 기존에 같은 날짜에 등록된 레코드가 있다면 금액, 수량 누적
   -- 금액 = 기존 금액 + 새로운 금액
   -- 수량 = 기존 수량 + 새로운 수량  
            UPDATE sales SET dayamount=dayamount+:new.amount, dayqty=dayqty+:new.qty
            WHERE sdate = :new.sdate; -- 날짜가 같은 레코드    
        ELSE -- 기존에 등록된 날짜가 없다면 새로 레코드 추가
            INSERT INTO sales(sdate, dayamount, dayqty)
            VALUES(:new.sdate, :new.amount, :new.qty);     
        END IF;
    ELSIF DELETING THEN  -- 레코드 삭제일 경우, 금액, 수량 삭제
   -- :old: 삭제된 레코드를 가지고 있는 객체
   -- 같은 날짜에 한해서 금액 및 수량을 감산 합니다.
        UPDATE sales SET dayamount=dayamount-:old.amount, dayqty=dayqty-:old.qty
        WHERE sdate = :old.sdate;     
    END IF;
END;
/
 
 
 
 
 
DELETE FROM advance_sale;
DELETE FROM sales;
COMMIT;
 
 
 
 
 
3. 새로운 날짜의 매출이 발생한 경우 INSERT Test
 
INSERT INTO advance_sale(num, sdate, qty, amount)
VALUES(1, TO_CHAR(sysdate, 'yyyy-mm-dd'), 1, 5000);
 
SELECT * FROM advance_sale;
       NUM      SDATE                                    QTY        AMOUNT
     ---------- ------------------------------         ----------   -------------
         1         2006-11-13                                 1          5000
     1 row selected
 
 
-- 매출액 테이블
SELECT sdate, dayamount, dayqty FROM sales;
      SDATE                                    DAYAMOUNT     DAYQTY
     ------------------------------          ----------        --------------
     2006-11-13                                 5000                1
    1 row selected
 
 
 
 
 
4. 같은 날짜에 매출이 발생한 경우 UPDATE Test
 
INSERT INTO advance_sale(num, sdate, qty, amount)
VALUES(2, TO_CHAR(sysdate, 'yyyy-mm-dd'), 1, 5000);
 
SELECT * FROM advance_sale;
       NUM     SDATE                                 QTY          AMOUNT
     ---------- ------------------------------      ----------     ----------
         1         2006-11-13                              1            5000
         2         2006-11-13                              1            5000
2 rows selected
 
 
-- 매출액 테이블
SELECT sdate, dayamount, dayqty FROM sales;
 
SDATE                                   DAYAMOUNT  DAYQTY
------------------------------         ----------        ----------
2006-11-13                               10000             2
1 row selected
 
 
 
 
 
5. 날짜가 다른경우
- Oracle Server의 시간 변경후 테스트를 하던지 또는 sysdate+1을 합니다.
 
INSERT INTO advance_sale(num, sdate, qty, amount)
VALUES(3, TO_CHAR(sysdate+1, 'yyyy-mm-dd'), 1, 5000);
 
SELECT * FROM advance_sale
       NUM       SDATE                                 QTY         AMOUNT
      ---------- ------------------------------      ----------     ----------
         2          2006-11-13                              1            5000
         3          2006-11-13                              1            5000
         3          2006-11-14                              1            5000
      3 rows selected 
 
 
- 매출액 테이블
SELECT sdate, dayamount, dayqty FROM sales
SDATE                                   DAYAMOUNT     DAYQTY
------------------------------        ----------          ----------
2006-11-13                               10000                2
2006-11-14                               5000                 1
2 rows selected
 
 
 
 
 
6. 매출액이 취소되는 경우
 
 
DELETE FROM advance_sale WHERE num=1;
 
SELECT * FROM advance_sale;
       NUM     SDATE                                  QTY          AMOUNT
---------- ------------------------------ ---------- ----------
         2        2006-11-13                              1             5000
         3        2006-11-13                              1             5000
2 rows selected
 
 
-- 매출액 테이블
SELECT sdate, dayamount, dayqty FROM sales;
SDATE                                     DAYAMOUNT     DAYQTY
------------------------------          ----------            ----------
2006-11-13                                 5000                1
1 row selected
 create table product(
code char(6) not null,
name varchar2(25) null,
company varchar2(25) null,
price number null,
stock number null,
primary key (code)
);


create table inbound(
inno number not null,
indate date null,
inquantity number null,
inprice number null,
amount number null,
code char(6) not null,
primary key(inno),
foreign key(code) references product
);

insert into product
values('A001','세탁기','LG',500,0);

insert into product
values('A002','컴퓨터','LG',700,0);

insert into product
values('A003','냉장고','삼성',600,0);

create or replace trigger in_trigger
after insert or delete or update on inbound
for each row

declare

begin
if inserting then
update product set stock = stock + :new.inquantity
where code = :new.code;
elsif updating then
update product set stock = stock + :new.inquantity - :old.inquantity
where code = :old.code;
elsif deleting then
update product set stock = stock - :old.inquantity
where code = :old.code;
end if;
end;
/


insert into inbound(inno,code,indate,inquantity,inprice,amount)
values(1, 'A001', sysdate, 5,320,16000);
 
 
 
select * from inbound;
select * from product;


insert into inbound(inno,code,indate,inquantity,inprice,amount)
values(2, 'A002',sysdate, 8,500,4000);





update inbound
set inquantity = 200,
amount = 1000000
where inno = 2




[11] Trigger - 주문후 판매통계 누적하기 실습
[01] Trigger  실습

 - 주문이 이루어지면 판매통계 테이블에 월별 판매수량 판매금액 증가
 - 주문이 취소되면 
판매통계 테이블에 월별 판매수량 판매금액 감소

1. 테이블 구조

CREATE TABLE  porder (
       ono             INTEGER NOT NULL,
       odate           CHAR(10) NULL,
       oID              CHAR(8) NULL,
       oquantity      INTEGER NULL,
       oprice          INTEGER NULL,
       code            CHAR(6) NOT NULL,
       PRIMARY KEY (ono), 
       FOREIGN KEY (code)
                             REFERENCES product
);
 
 
 
CREATE TABLE sales_total (
       no                        NUMBER NOT NULL,
       yearmonth             CHAR(7) NOT NULL,  -- 년월
       code                     CHAR(6) NULL,
       monthsalesqty         NUMBER  NULL,      --월별판매수량
       monthsalesprice       NUMBER NULL,       --월별판매금액
       PRIMARY KEY (no)
);
 
 
CREATE SEQUENCE seq_no
    START WITH   1           --시작번호
    INCREMENT BY 1           --증가값
    MAXVALUE     99999       --최대값
    CACHE 20                 --시쿼스 변경시 자주 update되는 것을 방지하기위한 캐시값
    NOCYCLE;    



2.  주문이 생성되면 판매통계 테이블의 월별금액과 월별 수량이 증가 또는 감소되도록 Trigger 작성하세요.


3.  주문이 일어났을때 상품의 재고수량의 변화를 트리거로 추가 하세요.

 

 

ORACLE - 문자열 추출 (substr)

2009.03.02 22:51
left(), Oracle, right(), substr, 문자열 추출, 오라클 내장함수, 오라클 문자뽑기, 오라클 오른쪽문자

ORACLE 내장함수에는 
LEFT(), RIGHT() 함수가 없다.
substr 함수를 통해 똑같이 구현이 가능하다.

 

@ 3번째 자리부터 쭉-
SELECT substr('ABC권경안Z9', 3) FROM DUAL;
C권경안Z9

@ 4번째 자리부터 2글자
SELECT substr('ABC권경안Z9', 4, 2) FROM DUAL;
권경

@ 우측부터 추출하고 싶다면 마이너스(-) 기호를 사용하면 된다. 우측 2글자
SELECT substr('ABC권경안Z9', -2) FROM DUAL;
Z9

create table porder(

ono integer not null,

odate char(10) null,

oID char(8) null,

oquantity integer null,

oprice integer null,

code char(6) not null,

primary key(ono),

foreign key(code) references product

);


select * from product

select * from porder


insert into porder(ono, odate, oID, oquantity, oprice, code)

values(1, to_char(sysdate, 'yyyy-MM-dd'), 'kim', 2 ,1000,'A001');


create table sales_total(

no number not null,

yearmonth char(7) not null, --년월

code char(6) null,

monthsalesqty number null, --월별 판매 수량

monthsalesprice number null, --월별 판매 금액

primary key(no)

);


select * from sales_total




 - 주문이 이루어지면 판매통계 테이블에 월별 판매수량 판매금액 증가

 - 주문이 취소되면 판매통계 테이블에 월별 판매수량 판매금액 감소

 

 create sequence seq_no

  start with 1

  increment by 1

  maxvalue 99999

  cache 20

  nocycle;

 

 

 

 

 

 2.  주문이 생성되면 판매통계 테이블의 월별금액과 월별 수량이 증가 또는 감소되도록 

 Trigger 작성하세요.


 

 

 CREATE OR REPLACE TRIGGER p_sales

AFTER INSERT OR UPDATE OR DELETE ON porder 

FOR EACH ROW  

DECLARE 

    v_cnt NUMBER;

    v_date char(7) := '';

BEGIN  

    DBMS_output.put_line(substr(:new.odate,1,7));

v_date := substr(:new.odate,1,7);

    SELECT count(*) INTO v_cnt FROM sales_total 

    WHERE yearmonth = v_date;

    

    IF INSERTING THEN 

        IF v_cnt > 0 THEN 

            UPDATE sales_total 

            SET monthsalesqty=monthsalesqty+:new.oquantity, 

                monthsalesprice=monthsalesprice+:new.oprice

            WHERE yearmonth = v_date;  

        ELSE 

            INSERT INTO sales_total

            (no, yearmonth, monthsalesqty,monthsalesprice,code)

            VALUES(seq_no.nextval,v_date,:new.oquantity

            ,:new.oprice,:new.code);     

        END IF;

    ELSIF DELETING THEN  

         UPDATE sales_total 

         SET monthsalesqty=monthsalesqty+:old.oquantity, 

             monthsalesprice=monthsalesprice+:old.oprice

         WHERE yearmonth = v_date;     

    END IF;

END;

/

 

insert into porder(ono,odate,oid,oquantity,oprice,code)

values(1,'2016-07-24','user2',1,500,'A001');

insert into porder(ono,odate,oid,oquantity,oprice,code)

values(2,'2016-07-24','user2',2,1400,'A002');

insert into porder(ono,odate,oid,oquantity,oprice,code)

values(3,'2016-07-24','user2',2,1400,'A002');


select * from sales_total


select substr('2016-06-24',1,7) from dual

 

 



[12] CallableStatement를 이용한 Update, Out Parameter
[01] CallableStatement를 이용한 PL/SQL의 호출
 
1. Oracle DB 설정
 
>>>>> 실습용 테이블
-------------------
 
DROP TABLE DEPT CASCADE CONSTRAINTS;
 
-- 부서 테이블
CREATE TABLE DEPT
( 
        DEPTNO NUMBER(2),
        DNAME VARCHAR2(14),
        LOC VARCHAR2(13) 
);
 
 
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH',   'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES',      'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
 
 
 
 
DROP TABLE EMP CASCADE CONSTRAINTS;
 
-- 직원 테이블
CREATE TABLE EMP
(
        EMPNO     NUMBER(4) NOT NULL,
        ENAME      VARCHAR2(10),
        JOB           VARCHAR2(9),
        MGR          NUMBER(4),
        HIREDATE    DATE,
        SAL            NUMBER(7, 2),
        COMM        NUMBER(7, 2),
        DEPTNO      NUMBER(2)
);
 
 
DELETE FROM EMP;
 
 
INSERT INTO EMP VALUES(7654, 'MARTIN', 'SALESMAN',  7698,
        sysdate, 1250, 1400, 30);
INSERT INTO EMP VALUES(7698, 'BLAKE',  'MANAGER',   7839,
        sysdate,  2850, NULL, 30);
INSERT INTO EMP VALUES(7782, 'CLARK',  'MANAGER',   7839,
       sysdate,  2450, NULL, 10);
INSERT INTO EMP VALUES(7788, 'SCOTT',  'ANALYST',   7566,
        sysdate, 3000, NULL, 20);
INSERT INTO EMP VALUES(7839, 'KING',   'PRESIDENT', NULL,
        sysdate, 5000, NULL, 10);
 
 
SELECT * FROM EMP;
 
 
COMMIT;
 
 
 
 
 
2. 프로시저의 생성 및 테스트 
   - 부서번호, 급여 인상률을 입력받아 급여를 인상하는 프로시져를 생성합니다.
 
CREATE or REPLACE PROCEDURE proc1
(
    i_deptno IN number,        -- 부서 번호
    i_increase_rate IN number  -- 급여 인상율
)
IS
BEGIN
    UPDATE EMP set sal = sal * i_increase_rate
    WHERE deptno = i_deptno;
END;
/
 
 
 
 
SELECT * FROM emp WHERE deptno=10 ORDER BY deptno;
 
     EMPNO  ENAME      JOB                 MGR        HIREDATE      SAL       COMM     DEPTNO
   --------- ----------     ---------           ----------    -----------    ----------    --------    ----------
      7782      CLARK      MANAGER        7839         81/06/09          2450                      10
      7839      KING         PRESIDENT                     81/11/17          5000                      10
 
 
 
 
DECLARE
    i_deptno number :=10;
    i_increase number(2,1) := 1.1;
BEGIN
    proc1(i_deptno, i_increase);
END;
/
 
 
 
 
SELECT * FROM emp WHERE deptno=10 ORDER BY deptno;
 
     EMPNO ENAME      JOB                 MGR    HIREDATE        SAL       COMM     DEPTNO
   ---------- ----------   ---------        ----------   --------           --------   ----------  ----------
      7782     CLARK      MANAGER         7839    81/06/09           2695                      10
      7839     KING        PRESIDENT                  81/11/17           5500                      10
 
 
 
   SELECT * FROM emp WHERE deptno=10 ORDER BY deptno;
 
 
 
 
 
3. CallableStatement를 실행
 
>>>>> Proc1.java
 
package test.plsql;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
 
public class Proc1 {
 
    public Proc1(){ }
    
    public static void main(String[] args) {
        String driver="oracle.jdbc.driver.OracleDriver";
        String url="jdbc:oracle:thin:@127.0.0.1:1521:XE";
        String id = "soldesk";
        String password = "1234";
        
        Connection con = null;
        
        // PL/SQL 처리
        //--------------------------------
        CallableStatement cstmt = null;
        //--------------------------------
        try{
            Class.forName(driver);
            con = DriverManager.getConnection(url, id, password);
 
            // call 명령은 프로시저를 호출합니다.
            cstmt = con.prepareCall("{call proc1(?,?)}");
            
            // 프로시저에 넘겨줄 인수 지정
            cstmt.setInt(1, 10);
            cstmt.setFloat(2, 1.5f);
            cstmt.executeUpdate();
            
            System.out.print("로직 처리 완료");
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{ cstmt.close(); }catch(Exception e){}
            try{ con.close(); }catch(Exception e){}    
        }
        System.out.println("정상적으로 실행되었습니다.");
    }
}
 
 
 
 
SQL> select * from emp where deptno=10 order by deptno;
 
     EMPNO     ENAME        JOB            MGR     HIREDATE      SAL       COMM      DEPTNO
     ----------   ----------     ---------       ----------   --------      ----------  ---------- ----------
      7782        CLARK      MANAGER      7839      81/06/09       2695                     10
      7839        KING        PRESIDENT                 81/11/17       5500                      10
 
 
 
 
 
4. Out Parameterm의 사용
   - 부서번호를 입력받아 직원수를 리턴합니다.
 
CREATE or REPLACE PROCEDURE proc2(
    i_deptno IN number, -- 부서 번호
    o_count OUT number  -- 직원 수
)
IS
BEGIN
    SELECT count(*) INTO o_count FROM EMP
    WHERE deptno = i_deptno;
END;
/
 
 
 
 
-- 직원수 출력
SELECT count(*) as o_count FROM EMP
WHERE deptno = 10;
 
 
 
-- Toad에서 DBMS Output을 Enable 하고 실행
 
DECLARE
    i_deptno number :=10;
    o_count number := 0;
BEGIN
    proc2(i_deptno, o_count);
    DBMS_OUTPUT.PUT_LINE(o_count);
END;
/
 
 
 
 
 
>>>>> Proc2.java
 
package test.plsql;
 
import java.sql.*;
import java.io.*;
 
public class Proc2 {
 
    public Proc2(){ }
    
    public static void main(String[] args) {
        try{
            String driver="oracle.jdbc.driver.OracleDriver";
            String url="jdbc:oracle:thin:@127.0.0.1:1521:XE";
            String id = "soldesk";
            String password = "1234";
            Class.forName(driver);
            Connection conn = DriverManager.getConnection(url, id, password);
 
/*
CREATE or REPLACE PROCEDURE proc2(
    i_deptno IN number, -- 부서 번호
    o_count OUT number  -- 직원 수
)
IS
BEGIN
    SELECT count(*) INTO o_count FROM EMP
    WHERE deptno = i_deptno;
END;
/
 
*/
            CallableStatement cstmt = conn.prepareCall("{call proc2(?,?)}");
            
            cstmt.setInt(1, 10);
            // output 파라미터의 지정
            cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
            cstmt.executeUpdate();
            
            // Output 파라미터를 가져오는 부분, output 파라미터는 2번째 
            // 임으로 getInt(2)를 지정 합니다.
            System.out.println("10번 부서의 직원수: " + cstmt.getInt(2));
        }catch(Exception e){
            System.out.println(e.toString());
        }
        System.out.println("정상적으로 실행되었습니다.");
    }
}
 
 

PreparedStatement & CallableStatement

2010.02.16 15:38 in Information Technology

Connection 에 의한 SQL 처리는 크게 3가지로 나뉘어 진다.

  1. Statement : 단순히 sql문을 실행하는 역할만 한다.(값을 sql문에 +연산자로 추가해야 한다.) 
  2. PreparedStatement : sql 문에 ? 를 사용해서 값을 간편히 추가한다. 
  3. CallableStatement : DB에 생성된 저장프로시저를 사용한다. 역시 ? 사용가능

 

Statement 객체를 만들기 위해서는 사용되는 Connection 클래스의 메서드

  1. Statement stmt = conn.creatStatement(); 
  2. PreparedStatement pstmt = conn.prepareStatement(String sql) 
  3. CallableStatement cstmt = conn.prepareCall(String sql)

 

-----------------------------------------------------------
Statement
-----------------------------------------------------------

Statement 인터페이스는 Connection 객체로부터 Instance 화 하여 만들어 내며, DB에 SQL을 보내기 위한 준비 작업과 실제 SQL을 실행하여 결과값을 주는 API 를 제공한다.

Statement의 주요 메소드

execute()
execute()라는 메소드는 질의문(SELECT)이나 갱신문(UPDATE, INSERT, DELETE) 모두 사용할 수 있다. 질의문의 결과(ResultSet)를 얻기 위해서는 별도로 마련된 getResultSet()이라는 메소드를 사용해야 한다.

executeQuery()
executeQuery()메소드는 주로 SELECT문을 Database로 넘겨 실행시키고자 할 때 사용한다.
이 메소드는 ResultSet객체를 Return하며, Argument로는 Query할 SELECT문장을 String형태로 받는다.

executeUpdate()
executeUpdate()메소드는 INSERT문이나 CREATE문, DELETE문 같이 Database를 갱신(update)할 때 사용하는 메소드이다. 이 메소드는 갱신된 행의 수를 반환한다.




<<<<<<<<<<<< JSP >>>>>>>>>>


<%
DataSource ds = null;

Connection conn = null;
java.sql.Statement stmt = null;

PreparedStatement pstmt;
CallableStatement pstmt2;

ResultSet rs= null;

try{
 initContext = new InitialContext();
 envContext = (Context) initContext.lookup("java:comp/env"); 
 ds = (DataSource) envContext.lookup("jdbc/KSFC");
 conn = ds.getConnection();
 stmt = conn.createStatement();

 int SqlNo = 1; 
 String SP_SQL1 = "{CALL ODS..SP_EM002_Proc(?,?,?,?,?,?)}" ;
     pstmt2 = conn.prepareCall(SP_SQL1);
     pstmt2.clearParameters();
     pstmt2.setInt(1,SqlNo);
     pstmt2.setString(2,firstdt);
     pstmt2.setString(3,startdt);
     pstmt2.registerOutParameter(4,java.sql.Types.DECIMAL); 
     pstmt2.registerOutParameter(5,java.sql.Types.DECIMAL); 
     pstmt2.registerOutParameter(6,java.sql.Types.DECIMAL);
     pstmt2.execute(); 

 double pung1 = 0.0;
 double pung2 = 0.0;
 double pung3 = 0.0;

 pung1 = pstmt2.getDouble(4);
 pung2 = pstmt2.getDouble(5); 
 pung3 = pstmt2.getDouble(6); 
 

 SqlNo = 2; 
 String SP_SQL2 = "{CALL ODS..SP_EM002_Proc(?,?,?,?,?,?)}" ;
     pstmt = conn.prepareStatement(SP_SQL2);
     pstmt.clearParameters();
     pstmt.setInt(1,SqlNo);
     pstmt.setString(2,firstdt);
     pstmt.setString(3,startdt);
     rs = pstmt.executeQuery(); 
              
 double pung2 = 0;
 while(rs.next())
 {
  pung2 = rs.getDouble(1);
 } rs.close();
%>
<% 
 stmt.close();
}catch(Exception e){
 out.println(e);
}finally{
 try{if(stmt != null) stmt.close();} catch(Exception e){}
 try{if(conn != null) conn.close();} catch(Exception e){}
}
%>  





<<<<<<<<<<<< SP >>>>>>>>>>


create PROCEDURE [dbo].[SP_EM_002_Proc]
    @SqlNo  AS INT , 
    @firstDt AS VARCHAR(8), 
    @startDt AS VARCHAR(8),
    @PUNGJAN_1  AS  DECIMAL(20,0)   OUTPUT,
    @PUNGJAN_2  AS  DECIMAL(20,0)   OUTPUT,
    @PUNGJAN_3  AS  DECIMAL(20,0)   OUTPUT
 
AS 
]

[14] Sequence를 가져오는 Stored Procedure의 제작
[01] Sequence를 가져오는 Stored Procedure의 제작
 
CREATE TABLE sequence (
       seqname              VARCHAR(20) NOT NULL, --table명
       seqnum               NUMBER(10) NOT NULL,--일렬번호
       PRIMARY KEY (seqname)
);
 
 
1. Stored Procedure
 
CREATE OR REPLACE PROCEDURE sequence_write(
     i_seqname IN sequence.seqname%TYPE,
     o_seqnum OUT sequence.seqnum%TYPE
) 
IS  
     v_count number;
BEGIN
    
    SELECT count(*) into v_count 
    FROM sequence
    WHERE seqname = i_seqname;
 
    if(v_count>0) then
        UPDATE sequence 
        SET seqnum = seqnum + 1
        WHERE seqname = i_seqname;
    elsif(v_count=0) then
        INSERT into sequence(seqname,seqnum)
        VALUES(i_seqname,1);
    end if;
    
    COMMIT;
    
    SELECT seqnum
    INTO o_seqnum
    FROM sequence
    WHERE seqname = i_seqname; 
 
END sequence_write;
/
 
 
 
-- 테스트
 
SELECT * FROM sequence;
 
DECLARE
    o_seqnum  number := 0;
BEGIN
   sequence_write('bbs', o_seqnum);
   DBMS_OUTPUT.PUT_LINE('일련번호 추출: ' || o_seqnum);
 
END;
/
 
 
 
 
 
2. JAVA 에서의 사용
 
>>>>> Sequence_write.java
 
package test.plsql;
 
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
 
public class Sequence_write2 {
 
    public static void main(String[] args) {
        try{
            String driver="oracle.jdbc.driver.OracleDriver";
            String url="jdbc:oracle:thin:@127.0.0.1:1521:XE";
            String id = "soldesk";
            String password = "1234";
 
            Class.forName(driver);
            Connection conn = DriverManager.getConnection(url, id, password);
 
            CallableStatement cstmt = conn.prepareCall("{call sequence_write2(?,?)}");
            
            cstmt.setString(1, "communityData");
            // output 파라미터의 지정
            cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
            cstmt.executeUpdate();
            
            // Output 파라미터를 가져오는 부분, output 파라미터는 2번째 
            // 임으로 getInt(2)를 지정 합니다.
            System.out.println("communityData 일련 번호: " + cstmt.getInt(2));
        }catch(Exception e){
            System.out.println(e.toString());
        }
        System.out.println("정상적으로 실행되었습니다.");
    }
}
















































































































































































































































































































 



5. 수업

진도: 

hw: 


6. 할것


오 오늘 드디어 홈페이지 끝냄 :-D


뷰나 트리거 - callablestatement를 쓰는 것이 아니고
storedprocedure만 callablestatmenet를 씀 



dbmodeling -> ojt랑 같이 시작하는 것

시간 줄 때 홈페이지 체크 전에 pl-sql  복습 할 것

'Programming' 카테고리의 다른 글

160628: 73회차  (0) 2016.06.28
160627: 72회차  (0) 2016.06.27
160623: 70회차  (0) 2016.06.23
160622: 69회차  (0) 2016.06.22
160621: 68회차  (0) 2016.06.21
Posted by DAVID
블로그 이미지

by DAVID

공지사항

    최근...

  • 포스트
  • 댓글
  • 트랙백
  • 더 보기

태그

글 보관함

«   2025/07   »
일 월 화 수 목 금 토
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

링크

카테고리

PC (112)
Programming (109)

카운터

Total
Today
Yesterday
방명록 : 관리자 : 글쓰기
DAVID's Blog is powered by daumkakao
Skin info material T Mark3 by 뭐하라
favicon

PC

  • 태그
  • 링크 추가
  • 방명록

관리자 메뉴

  • 관리자 모드
  • 글쓰기
  • PC (112)
    • Programming (109)

카테고리

PC화면 보기 티스토리 Daum

티스토리툴바