본문 바로가기

PL SQL

PL/SQL - 프로시저, 함수, 커서, 패키지, 트리거

@markdown

## PL/SQL 저장 프로시저

____


- 작성한 PL/SQL을 저장해 놓고 필요한 경우 호출하여 사용할 때 

- 오라클은 사용자가 작성한 PL/SQL 문을 데이터베이스에 저장 할 수 있도록 저장프로시저 기능 제공

- 배치 작업, 복잡한 로직, 많은 데이터 활용해서 건드리는 작업에 용이


<pre><code class="sql" style="font-size:14px">CREATE [OR REPLACE ] PROCEDURE prcedure_name

( 변수 [mode] 자료형, 변수 [mode] 자료형 ... )

IS

지역변수 선언

BEGIN

...

END;

/

</code></pre>


### mode 종류

- `in` : 실행시 입력되는 것을 받는다

- `out` : 실행 후 호출한 곳으로 값을 return

- `in out` : 실행시 입력되는 것을 받는다. 실행 후 호출한곳으로 값을 return


- 실행 : execute 프로시저이름(파라미터1, 파라미터2 ...)

- execute 프로시저 or 함수이름(in변수, :out변수)

- 파라미터가 in이면 값 또는 변수가능, 값을 파라미터 전달

- 파라미터가 out이면 변수만 가능, 변수이름을 전달하면서 `:`을 사용하여 :변수이름 으로 사용 

- `execute 프로시저 이름(:변수)`

- 파라미터가 `in out`이면 변수만 가능


## PL/SQL 저장 함수

____

- 저장 함수는 저장 프로시저와 용도는 비슷하지만, 실행결과를 되돌려 받을 수 있다

- 단순 로직에 필요한 부분만 함수로 정의해서 간단하게 사용할때 용이

- 함수 실행 방법

  1. 함수 작성

  2. 함수 생성

  3. select 문에서 함수 사용


<pre><code class="sql" style="font-size:14px">CREATE [OR REPLACE ] PROCEDURE prcedure_name

( 변수 [mode] 자료형, 변수 [mode] 자료형 ... )

return number

IS

지역변수 선언

BEGIN

...

END;

/


SQL > EXECUTE :변수이름 := 함수이름(파라미터);

</code></pre>


- 직원들의 급여 보너스를 계산하는 함수 작성

<pre><code class="sql" style="font-size:14px">create or replace function func_bonus(v_empno in number, v_per in number)

return number

is

v_name emp.ename%type;

v_sal emp.sal%type;

begin

select ename, sal

into v_name, v_sal

from emp

where empno = v_empno;

return v_sal*v_per;

end;

/

</code></pre>


- 작성한 함수는 select문에서 컬럼이름을 파라미터 값으로 지정해 사용할 수 있다. 

<pre><code class="sql" style="font-size:14px">select ename, sal, func_bonus(empno, 2), lower(ename)

from emp

</code></pre>


## PL/SQL 커서

____

- select 문장 수행 후 반환되는 여러개의 행을 처리하기 위해 사용한다.

- 커서에는 명시적 / 암시적 방법으로 선언할 수 있다.

- fetch문을통해 로우에 대한 결과값을 처리할 수 있다.


### 명시적 커서

____


<pre><code class="sql" style="font-size:14px">create or replace procedure 명시적_커서_프로시저

is

변수 선언;

--커서 선언

cursor 커서이름 is select empno, ename, sal from emp;

begin

--커서 실행

open 커서이름;

loop

--데이터 가져오는 부분 fetch문 : 행 단위로 데이터를 읽는다.

fecth 커서이름 into 전달받을 변수1, 변수2, 변수3

--반복문 탈출 조건

exit when 커서이름%notfound;

dbms_output.put_line(변수1 || 변수2 || 변수3);

end loop;

--커서 종료

close 커서이름;

end;

/

</code></pre>


### 암시적 커서

- for문을 이용하여 간단하게 암시적으로 커서를 생성하고, 반복문을 통해 데이터를 가져올 수 있다.

- for loop에서 각 반복마다 커서를 열고 행을 fetch한다.

- 모든 행이 처리되고 난 후 자동으로 커서가 닫히기 때문에 사용하기 편리하다.


<pre><code class="sql" style="font-size:14px">create or replace procedure 암시적_커서_프로시저

is

begin

--암시적인 커서

--레코드 변수 이름 지정 후 select 문 결과를 한 행씩 가져와 레코드에 저장한다.

for v_emp_rec in (select empno, ename, sal from emp) 

loop

dbms_output.put_line('직원정보 : ' || v_emp_rec.empno || ' ' || v_emp_rec.ename || ' ' || v_emp_rec.sal);

end loop;

end;

/

</code></pre>


## PL/SQL 패키지

____

- 패키지 : 프로시저나 함수를 효율적으로 관리하기 위해 패키지 단위로 배포할 때 사용된다.

- 패키지는 패키지 선언(명세부)과 패키지 몸체 선언(몸체부) 두 가지 모두를 정의해야 합니다.

- 구성 : 선언부와 구현부로 나누어 패키지 등록을 한다.

- 선언부 : 프로시저 or 함수 헤더 부분만 작성


- 패키지 선언부

<pre><code class="sql" style="font-size:14px">create or replace package mypkg

is

procedure sp_emp7;

function func_tax(v_salary number) return number;

end;

/

</code></pre>


- 구현부 : 선언부에서 선언된 함수 헤더를 구현하는 부분을 작성


- 패키지 바디(구현부)

<pre><code class="sql" style="font-size:14px">create or replace package body mypkg

is

procedure sp_emp7

is

begin

--암시적인 커서

for v_emp_rec in (select empno, ename, sal from emp) 

loop

dbms_output.put_line('직원정보 : ' || v_emp_rec.empno || ' ' || v_emp_rec.ename || ' ' || v_emp_rec.sal);

end loop;

end sp_emp7;

function func_tax(v_salary in number) return number

is

begin

return v_salary * 0.07;

end func_tax;

end;

/

</code></pre>


- 사용 : 패키지이름.프로시저 이름 or .함수이름

- 패키지 실행 : `execute mypkg.sp_emp7();`

- select문 패키지함수 호출 : `select ename, sal, mypkg.func_tax(sal) from emp;`



## PL/SQL 트리거

____

- 트리거는 특정 이벤트 전/후로 자동으로 실행되는 프로시저 or 함수이다.

- 자동 실행 프로시저 / 함수

- 트리거 사용


<pre><code class="sql" style="font-size:14px">CREATE TRIGGER 트리거이름 timing[BEFORE|AFTER] event[INSERT|UPDATE|DELETE]

ON 테이블이름

[FOR EACH ROW]

[WHEN conditions]

BEGIN

트리거 수행 문장

END

</code></pre>


### 트리거의 타이밍

- before : 테이블에 INSERT, UPDATE, DELETE 문이 실행될 때, 해당 문장이 실행되기 전에 트리거가 가지고 있는 BEGIN ~ END 사이의 문장을 실행한다.

- after : INSERT, UPDATE, DELETE 문이 실행되고 난 후에 트리거가 가지고 있는 BEGIN ~ END 사이의 문장을 실행한다.


### 트리거의 이벤트

- 어떤 DML문이 실행됐을때 트리거를 발생시킬 것인지 결정하는 옵션


### 트리거의 몸체

- 트리거 수행 문장을 BEGIN ~ END에 기술


### 트리거의 유형

- for each row에 의해 문장 레벨 트리거와 Row 레벨 트리거로 나눈다.

- 문장 레벨 트리거 : 테이블에 DML 문 실행되면, 트리거를 딱 한번 실행하는 것

- Row 레벨 트리거 : DML에 의해 여러 개의 행이 변경될때, 각 행이 변경될 때마다 트리거를 발생시키는 방법




<pre><code class="sql" style="font-size:14px">insert 문장 발생 후 콘솔에 출력하는 트리거 코드

CREATE OR REPLACE TRIGGER new_employee_trg

AFTER INSERT

ON EMP

BEGIN

DBMS_OUTPUT.PUT_LINE('신입사원 생성');

END;

/

</code></pre>

'PL SQL' 카테고리의 다른 글

PL/SQL 연습  (0) 2017.05.18
PL/SQL - 기초(구조, 변수, 문법)  (0) 2017.05.18