◎ 서브 프로그램 

PL/SQL로 만든 또다른 프로그램, 한번 만들어 놓고 저장해 놓은 것 

 ↔ 저장을 안해 놓으면 익명 블럭 


◎ 종류

 ① 프로시저

 ② 함수

 ③ 패키지

 ④ 트리거 


□ 프로시저 

  어떠한 작업을 하는 프로그램  

  별도의 컴파일 없이 생성된 P_CODE를 실행

  SP : stored procedure 

※ 변수의 위치에 따라서 PL/SQL이 다르게 인식함 

※ 변수 종류

 - 사용자에게 입력 받는 변수 : CREATE 와 IS 사에 있어야함  

 - 테이블에서 가져와서 저장하는 변수 : IS 와 BEGIN  사이에 있어야함 

   변수 MODE

 - IN :  외부에서 PL/SQL 로 인자값을 념겨줌 (DEAFAULT)

  - OUT : PL/SQL 의 변수 값을 외부로 인자값을 넘겨줌(다른프로시져도 가능)

절차

① CREATE 를 통해서 프로시저를 생성한다 

② 받을 인자값, 밖으로 보낼 인자값을 선언한다 (IS , CREATE 사이에 만듬)

     이때 프로시저를 사용할때 와 순서가 같아야 함 

   CREATE 프로지서 (인자1, 인자2 , 인자3)=프로시저(인자1, 인자2, 인자3);

③ 필요 하면 테이블에서 가져올 변수를 담을 곳을 만들어줌 (IS  BEGIN 사이)

④ PL/SQL 블럭을 만듬 

-- 프로시저 사용시--

⑤  프로시저 사용시 EXEC ②; 같이 해서 사용해 주어야 함 

CREATE [OR REPLACE] PROCEDURE procedure_name

[( parameter1 [mode1] datatype1,

parameter2 [mode2] datatype2,

… )]

IS | AS

PL/SQL Block ;

CREATE OR REPLACE PROCEDURE ename_sal

 -- 외부에서 입력되는 데이터 CREATE ,IS 사이 (IN 생략)

( vempno emp.empno%TYPE )


IS

  -- 테이블에 서 가져오는 데이터 IS, BEGIN 사이 (IN 생략)

 vename emp.ename%TYPE ;

 vsal emp.sal%TYPE ;


 BEGIN

 -- 1건의 데이터만 일때 사용 하기 

 SELECT ename , sal INTO vename , vsal

 FROM emp

 WHERE empno=vempno;

  

 DBMS_OUTPUT.PUT_LINE ('Name is '||vename);

 DBMS_OUTPUT.PUT_LINE ('Sal is '||vsal );

 END;

 /


실행문장

exec ename_sal(&in);

※ 프로시저를 실행할때() 안에 지정한 변수를 순서대로 전부 적어주어야함 

-- 프로시저 만들기

CREATE OR REPLACE PROCEDURE info_emp

-- ☆ 아래의 실행시에 순서와 같음  info_emp(7782,v_sal2,v_ename2)

 (  v_empno IN emp.empno%TYPE ,

  -- 이름값을 저장할 변수임

   v_sal OUT emp.sal%TYPE,

 -- 급여를 저장할 변수임 

 v_ename OUT emp.ename%TYPE 

  

  ) 

 IS

 BEGIN

 -- 테이블 데이터를 빼와서 외부로 나갈수 있는 변수에 저장 

 SELECT ename , sal INTO v_ename , v_sal

 FROM emp

 WHERE empno = v_empno ;

 END ;

 /


--실행블록 생성

DECLARE

 -- 인자값을 받을 것을 설정 

 v_ename2 emp.ename%TYPE ;

 v_sal2 emp.sal%TYPE ;

 BEGIN

--  위에 프로시저의 순서와 같음

-- 프로시저에서 반환한 값을 다시 받음 

  info_emp(7782,v_sal2,v_ename2) ;

 DBMS_OUTPUT.PUT_LINE (v_sal2||' ''s salary is '||v_ename2);

 END ;

 /

□ 함수 

  프로시져와 거이 비슷 하지만 return 값이 있음 

  프로시저도 out을 사용해서 return 값이 있음 

  2개의 칼럼을 리턴하는 함수는 없음

 절차

① 함수를 선언 하고  들어올 인자값 을 설정한다, (IS CREATE 사이에 만듬)

②  RETURN TYPE를 설정한다 . 

③  테이블에서 뽑아온 데이터를 저장하는 변수를 생성 (IS BEAGIN 사이에 만듬)

④  내부 PL/SQL을 만들고

⑤ 연산이 종료 되면 RETURN을 하는데 IS BEAGIN  사이에 변수를 해줌 

CREATE [OR REPLACE] FUNCTION function_name

[( parameter1 [mode1] datatype1,

parameter2 [mode2] datatype2,

… )]

RETURN datatype

IS | AS

PL/SQL Block ;

CREATE OR REPLACE FUNCTION max_sal

 -- 외부로 부터 인자값을 받음 

 (v_deptno emp.deptno%TYPE )

 -- 반환할 데이터 타입형이 무엇인지 정해줌 

 RETURN NUMBER

 

 IS

-- 데이터를 뽑아온 후저장할 변수를 선언해줌  

 max_sal emp.sal%TYPE ;

 

 BEGIN

 SELECT max(sal) INTO max_sal

 FROM emp

 WHERE deptno=v_deptno;


-- 이 부분의 데이터 형이 같아야 함

 RETURN max_sal ; 

 END;

 /

-- 그냥 함수 처럼 사용하면 됨 -

SELECT deptno , max_sal(deptno)

FROM emp

GROUP BY deptno

ORDER BY 1 ;

-  함수 내에 서브쿼리 사용하기 

CREATE OR REPLACE FUNCTION dname

-- 인자값 데이터

 (v_profno IN professor.profno%TYPE )

 RETURN VARCHAR2

 IS

 -- 테이블에서 가져올 이름 

 v_dname department.dname%TYPE ;

 BEGIN

 

 -- 첫번째 쿼리를 수행해서 이름을 가져온다음 

 SELECT dname INTO v_dname

 FROM department

 -- 1 쿼리에서 교수번호에 해당하는 deptno 를 가져와서 

 -- 서브쿼리에 넣어서 학과테이블에서 조회를 한 값을 넣음 

 WHERE deptno = ( SELECT deptno

           FROM professor

           WHERE profno=v_profno);

 

 RETURN v_dname ;

 END ;


 /

-조회 하기

SELECT text

FROM user_source

 WHERE type='FUNCTION'

-- 함수명

 AND name='MAX_SAL' ;


□ 패키지

  프로시져나 함수를 모듈 별로 모아둔 곳 

   선언부(Spec) + 몸체부(Body) 로 구성됨  

 - 선언부

  몸체부에서 프로시저에서 사용하는 파라미터를 미리 다 선언을 해줌 

CREATE [OR REPLACE] PACKAGE PACKAGE_name

IS | AS

Public type and item declarations

Subprogram specifications

END PACKAGE_name ;


CREATE OR REPLACE PACKAGE member_mg

IS

 

 --성별을 찾는 프로시저

 PROCEDURE find_sex 

 (v_name member.name%TYPE ) ;

 

 --id를 찾는 프로시저

 PROCEDURE find_id 

 ( v_name member.name%TYPE ,

   v_no member.jumin%TYPE ) ;

 

 -- 비밀번호를 찾는 프로시저 

 PROCEDURE find_pwd

 (v_id IN member.id%TYPE ,

  v_an IN member.an_key_dap%TYPE ) ;

 

 END member_mg ;

 /


◎  트리거

- 어떠한 이벤트가 발생했을때 미리 만들어진 이벤트를 실행 

  ex) 테이블에 상품이 입고되면 자동으로 재고테이블을 증가하게 만듬 

  TRIGGER 생성시 정의한 특정 사건에 의해서 묵시적인 자동 실행 

    잘못생성하면 종속관계가 심해짐 

◇ 종류

- 단순 DML 트리거 

  트리거의 실행 위치에 따라서 구분

  ① BEFORE TRIGGER(多)    

      테이블에서 작업을 하기 전에 트리거를 먼저수행 

 ex)데이터를 삭제 하기 전에 백업하기 등 

   ② AFTER TRIGER(多)

        테이블에서 DML 작업을 수행후에 TRIGER 실행 

   ③ INSTEAD OF TRIGGER (少)

   트리거 영향에 따른 구분 

     ① 문장 TRIGGER : 테이블 자체를 대상으로 실행하는 경우

  

     ② 행 TRIGGER : 특정 record 값을 대상으로 사용 

          사용시: FOR EACH ROW 

- 기타 DML 이아닌 TRIGGER (책참조)

CREATE [OR REPLACE] TRIGGER trigger_name

timing

event1 [ OR event2 OR event3 … ]

ON {table_name|view_name | SCHEMA | DATABASE}

[REFERENCING OLD AS old | NEW AS new]

[FOR EACH ROW [WHEN ( condition ) ] ]

TRIGGER_BODY


예제전 명령 실행하기 

GRANT create trigger TO scott;




CREATE OR REPLACE TRIGGER tri_order

  /* 프로세스

   데이터가 입력되기 전에 시간을

   체크하는것이 실행이 되야한다.  

  */

  BEFORE INSERT ON tab_order

  BEGIN

  IF (TO_CHAR(SYSDATE,'HH24:MI') NOT BETWEEN   '13:33' AND

  '13:50') THEN

  RAISE_APPLICATION_ERROR(-20100,'Time Error!!');

 END IF ;








조회하기

SELECT trigger_name , table_name , status

FROM user_triggers;


    






'ORACLE > PL/SQL' 카테고리의 다른 글

참조하기  (0) 2015.03.26
150324 예외처리  (0) 2015.03.24
150324 커서  (0) 2015.03.24
150323 조건문 & 반복문  (0) 2015.03.23
150323 변수  (0) 2015.03.23
Posted by 히드라야
,