오라클 트리거(Oracle Trigger), 트리거실행순서, Instead Of Trigger, Trigger Mutating Table Exception, Compound Triggers, Trigger Enable/Disable/Drop
http://ojc.asia/bbs/board.php?bo_table=LecSQLnPlSql&wr_id=585

오라클 트리거(Oracle Trigger), 트리거실행순서, Instead Of Trigger, Trigger Mutating Table Exception, Compound Triggers, Trigger Enable/Disable/Drop9. 트리거(Trigger) 9.1 트리거 개요, 기본문법 n 트리거링 이벤트에 대해 자동으로 실행되는 프로시저로 데이…
ojc.asia
9. 트리거(Trigger)
9.1 트리거 개요, 기본문법
n 트리거링 이벤트에 대해 자동으로 실행되는 프로시저로 데이터베이스에 저장되는 스키마 오브젝트 이다.
n 트리거링 이벤트
데이터 조작어(DML, Data Manipulation Language) : INSERT, UPDATE, DELETE
데이터 정의어(DDL, Data Definition Language) : CREATE, ALTER, DROP
데이터베이스 오퍼레이션 : SERVERERROR, LOGON, STARTUP or SHUTDOWN
n 트리거 타이밍
BEFORE : 이벤트가 발생하기 전에
AFTER : 이벤트가 발생한 후에
n FOR EACH ROW : DML의 영향을 받는 모든 행, 레코드마다 트리거가 작동되는 트리거를 행 트리거라고 하며 몇건의 데이터가 삽입, 삭제, 갱신되더라도 한번만 동작하는 트리거를 명령문 트리거라고 한다.
n FOR EACH ROW절이 있다면 행 트리거이고 행 트리거에 한해 레코드의 값을 제어할 수 있다.
:old : UPDATE 되기전의 값, DELETE 되기전의 값에 접근 가능
:new : INSERT 되는 값, UPDATE된 후의 값에 접근 가능
만약 :old, :new 대신 다른 키워드를 사용하려면 아래처럼 하면 된다.
CREATE OR REPLACE TRIGGER salary_change
BEFORE UPDATE ON EMP
REFERENCING new AS n old AS o
FOR EACH ROW
BEGIN
......
dbms_output.put_line(:n.ename);
END;
n WHEN : WHEN절에 조건을 줘서 조건에 맞는 경우에만 트리거가 동작되도록 할 수 있다.
CREATE [ OR REPLACE ] TRIGGER trigger_name [타이밍 AFTER/BEFORE] [이벤트1] [OR 이벤트2] …… ON table_name [ FOR EACH ROW ] -- 행트리거 여부를 결정, DML의 영향을 받는 레코드마다 트리거동작 [WHEN 조건] DECLARE 선언부 BEGIN -- 트리거 실행 코드 EXCEPTION END; |
--주말 오전10시에서 오후 6시 사이 EMP 테이블에 DML 사용못하게 하는 트리거 --아래는 명령문 트리거, 여러건이 DML의 영향을 받더라도 한번만 실행 SQL> create or replace trigger chk_emp_dml before insert or update or delete on emp begin if ((to_char(sysdate,'DY') in ('토','일')) AND (to_number(to_char(sysdate,'HH24'))) >= 10 AND (to_number(to_char(sysdate,'HH24'))) <= 18) THEN raise_application_error(-20001,'주말변경불가합니다.'); end if; end; / 트리거가 생성되었습니다.
SQL> update emp set sal = 0; update emp set sal = 0 * 1행에 오류: ORA-20001: 주말변경불가합니다. ORA-06512: "SCOTT.CHK_EMP_DML", 5행 ORA-04088: 트리거 'SCOTT.CHK_EMP_DML'의 수행시 오류
SQL> DROP TRIGGER chk_emp_dml;
-- 명령문 트리거 예제, FOR EACH ROW절이 없다. SQL> CREATE OR REPLACE TRIGGER CHK_EMP BEFORE INSERT OR UPDATE OF ename, sal OR DELETE ON emp BEGIN CASE WHEN INSERTING THEN DBMS_OUTPUT.PUT_LINE('Inserting...'); WHEN UPDATING('sal') THEN DBMS_OUTPUT.PUT_LINE('Updating sal...'); WHEN UPDATING('ename') THEN DBMS_OUTPUT.PUT_LINE('Updating ename...'); WHEN DELETING THEN DBMS_OUTPUT.PUT_LINE('Deleting...'); END CASE; END; /
트리거가 생성되었습니다.
SQL> SET SERVEROUTPUT ON SQL> insert into emp (empno, ename) values (88, '88길동'); Inserting... 1 개의 행이 만들어졌습니다.
SQL> delete from emp where empno = 88; Deleting... 1 행이 삭제되었습니다.
SQL> update emp set sal = sal + 10 where empno = 7369; Updating sal... 1 행이 갱신되었습니다.
SQL> update emp set ename = '오자바커' where empno = 7369; Updating ename... 1 행이 갱신되었습니다.
-- 행트리거 예제, FOR EACH ROW절이 있다. SQL> create table emp_bak ( old_sal number, new_sal number, u_date date, action varchar2(20)); 테이블이 생성되었습니다.
SQL> create or replace trigger tr_emp_update after update of sal on emp for each row begin insert into emp_bak values (:old.sal, :new.sal, sysdate,'UPDATE'); end; / 트리거가 생성되었습니다.
-- EMP테이블의 전체 레코드 24건에 대해 트리거가 발행된다. SQL> update emp set sal = sal + 500; Updating sal... 24 행이 갱신되었습니다.
SQL> select * from emp_bak;
OLD_SAL NEW_SAL U_DATE ACTION ---------- ---------- -------- -------------------- 800 1300 15/02/28 UPDATE 1600 2100 15/02/28 UPDATE …… 7777 8277 15/02/28 UPDATE 9998 10498 15/02/28 UPDATE
SQL> DROP TRIGGER CHK_EMP;
-- WHEN절을 이용하여 조건이 맞는 경우에만 트리거가 동작하도록 할 수 있다. SQL> CREATE OR REPLACE TRIGGER print_emp BEFORE UPDATE ON emp FOR EACH ROW WHEN (new.sal > 500) DECLARE sal_diff number; BEGIN sal_diff := :new.sal - :old.sal; dbms_output.put('OLD SALARY : ' || :old.sal); dbms_output.put(',NEW SALARY : ' || :new.sal); dbms_output.put_line(',급여차이 ' || sal_diff); END; / 트리거가 생성되었습니다. SQL> set serveroutput on SQL> update emp set sal = 0; 14 행이 갱신되었습니다. SQL> rollback; 롤백이 완료되었습니다. SQL> update emp set sal = 501; OLD SALARY : 800,NEW SALARY : 501,급여차이 -299 …… OLD SALARY : 1300,NEW SALARY : 501,급여차이 -799 14 행이 갱신되었습니다.
SQL> DROP TRIGGER print_emp; |
[LAB]
1. EMP 테이블에 데이터가 입력되면 EMP_OLD 테이블이 있다면 이 테이블에 insert 없다면 EMP_OLD 테이블을 만들고 이 테이블에 insert하는 행 레벨 트리거를 작성하세요. (입력되는 sal값이 3000보다 큰 경우에만 트리거 동작하도록)
트리거에서 create table 하는 방법에 대해 고민해 보세요! 2. EMP 테이블의 sal 칼럼에 변경이 일어나는 경우 sal_log 테이블의 empno, old_sal, new_sal, up_date(현재 날짜 입력) 칼럼에 값을 입력하고 ename 칼럼에 변경이 일어나는 경우 ename_log 테이블의 empno, old_ename, new_ename, up_date(현재 날짜 입력) 칼럼에 값을 입력하세요.
sal_log 및 ename_log 테이블은 각각 생성 하세요.
3. 'OJC1' 사용자로 로그인을 막는 Trigger를 작성하세요. - 로그온을 막을 USER는 DBA권한을 가져서는 안된다. - 이러한 트리거를 시스템 트리거라고 하며 SYS계정에서는 생성할 수 없으며 SYSTEM 계정 또는 DB의 로컬 관리자로 들어가서 만들어야 한다.
|
9.2 Setting Trigger Order
n 오라클에서 동일한 트리거링 이벤트, 타이밍에 대해 여러 개의 트리거를 작성하는 것은 가능하다.
n Oracle 11g 이후 동일한 트리거링 이벤트 및 트리거 타이밍에 대해 실행되는 트리거가 여러 개인 경우 FOLLOWS, PRECEDES 구를 통해 실행의 우선 순위를 정하는 것이 가능해 졌다.
[형식]
CREATE OR REPLACE TRIGGER [TRIGGER TO FOLLOW] [TIMING SPECIFICATION] [EVENT SPECIFICATION] FOLLOWS [TRIGGER TO BE FOLLOWED] |
SQL> SET SERVEROUTPUT ON SQL> CREATE OR REPLACE TRIGGER tr_follows_test1 BEFORE UPDATE ON emp FOR EACH ROW BEGIN DBMS_OUTPUT.put_line('tr_follows_test1 실행...'); END; / 트리거가 생성되었습니다.
SQL> CREATE OR REPLACE TRIGGER tr_follows_test2 BEFORE UPDATE ON emp FOR EACH ROW BEGIN DBMS_OUTPUT.put_line('tr_follows_test2 실행...'); END; / 트리거가 생성되었습니다.
SQL> update emp set sal = 9999 where ename = 'KING'; tr_follows_test2 실행... tr_follows_test1 실행...
SQL> CREATE OR REPLACE TRIGGER tr_follows_test2 BEFORE UPDATE ON emp FOR EACH ROW FOLLOWS tr_follows_test1 BEGIN DBMS_OUTPUT.put_line('tr_follows_test2 실행...'); END; /
트리거가 생성되었습니다.
SQL> update emp set sal = 9999 where ename = 'KING'; tr_follows_test1 실행... tr_follows_test2 실행... |
9.3 Instead Of Trigger
n 여러 테이블로 이루어진 뷰에 DML이 가해질 때 대신 trigger를 동작시킬 수 있는데 이때 사용하는 것이 instead of trigger 이다.
SQL> drop table employee; 테이블이 삭제되었습니다.
SQL> drop table department; 테이블이 삭제되었습니다.
SQL > CREATE TABLE department ( deptno NUMBER PRIMARY KEY, deptname VARCHAR2(20), manager_num NUMBER );
SQL> CREATE TABLE employee ( empno NUMBER PRIMARY KEY, empname VARCHAR2(20), deptno NUMBER REFERENCES department(deptno), startdate DATE );
SQL> CREATE OR REPLACE VIEW manager_info AS SELECT d.deptno, d.deptname, e.empno, e.empname FROM employee e, department d WHERE e.empno = d.manager_num;
SQL> CREATE OR REPLACE TRIGGER manager_info_insert INSTEAD OF INSERT ON manager_info FOR EACH ROW DECLARE employeeCount NUMBER; BEGIN SELECT COUNT(*) INTO employeeCount FROM employee e WHERE e.deptno = :new.deptno;
IF employeeCount >= 1 THEN UPDATE department d SET manager_num = :new.empno WHERE d.deptno = :new.deptno;
insert into employee (empno, empname, deptno, startdate) values (:new.empno, :new.empname, :new.deptno, sysdate);
ELSE insert into department(deptno, deptname, manager_num) values (:new.deptno, :new.deptname, 0);
insert into employee (empno, empname, deptno, startdate) values (:new.empno, :new.empname, :new.deptno, sysdate); END IF; END; /
SQL> INSERT INTO manager_info VALUES (11,'SALES',1004,'ANGEL'); 1 개의 행이 만들어졌습니다.
SQL> INSERT INTO manager_info VALUES (11,'SALES',1005,'SUJI'); 1 개의 행이 만들어졌습니다.
SQL> commit; 커밋이 완료되었습니다.
SQL> SELECT * FROM department;
DEPTNO DEPTNAME MANAGER_NUM ---------- -------------------- ----------- 11 SALES 1005
SQL> SELECT * FROM employee;
EMPNO EMPNAME DEPTNO STARTDAT ---------- -------------------- ---------- -------- 1004 ANGEL 11 16/05/01 1005 SUJI 11 16/05/01
SQL> INSERT INTO manager_info VALUES (21,'RND',1006,'SMITH'); 1 개의 행이 만들어졌습니다.
SQL> SELECT * FROM department;
DEPTNO DEPTNAME MANAGER_NUM ---------- -------------------- ----------- 11 SALES 1005 21 RND 0
SQL> SELECT * FROM employee;
EMPNO EMPNAME DEPTNO STARTDAT ---------- -------------------- ---------- -------- 1004 ANGEL 11 16/05/01 1005 SUJI 11 16/05/01 1006 SMITH 21 16/05/01
SQL> SELECT * FROM manager_info;
DEPTNO DEPTNAME EMPNO EMPNAME ---------- -------------------- ---------- -------- 11 SALES 1005 SUJI
|
9.4 Trigger Mutating Table Exception, Compound Triggers
n Mutating Table Exception : 행레벨 트리거(Row-Level Trigger)에서 변하고 있는 값을 참조하거나 변경하려고 할 때 발생되는 오류(ORA-04091: table XXX is mutating, trigger/function may not see it)
n Mutating 에러는 Insert, Update, Delete와 같은 DML이 수행되고 여기에 연결되어 있는 행레벨 트리거에서 변하는 값을 참조하는 경우 발생하는 오류이다.
n Mutating 에러는 Compund Trigger를 이용하여 해결할 수 있는데 하나의 트리거에 여러 개의 트리거링 타이밍을 기술하려면 COMPOUND TRIGGER구를 사용한다.
n 개별 트리거링 타이밍에서 밖에서 선언한 전역 변수에 대해 참조가 가능하므로 행 레벨 트리거에서 변하는 값들을 전역 변수(주로 배열처럼 쓰이는 테이블 타입의 컬렉션 변수)에 저장한 후 명령문 레벨 트리거의 AFTER 타이밍에서 한번에 처리함으로써 트리거에서 변하고 있는 값을 참조하는 경우 자주 발생하는 ORA-04091 에러를 방지할 수 있다.
[Compound Trigger 형식]
CREATE OR REPLACE TRIGGER 컴파운드_트리거이름 FOR 트리거링 이벤트 ON 테이블명 COMPOUND TRIGGER -- 전역 변수 선언 g_global_variable VARCHAR2(10);
BEFORE STATEMENT IS --명령문 레벨 트리거 BEFORE BEGIN NULL; -- Do something here. END BEFORE STATEMENT;
BEFORE EACH ROW IS --행레벨 트리거 BEFORE BEGIN NULL; -- Do something here. END BEFORE EACH ROW;
AFTER EACH ROW IS --행레벨 트리거 AFTER BEGIN NULL; -- Do something here. END AFTER EACH ROW;
AFTER STATEMENT IS --명령문 레벨 트리거 AFTER BEGIN NULL; -- Do something here. END AFTER STATEMENT;
END <trigger-name>; / |
1. 행레벨 트리거가 변하는 값을 참조하는 경우
CREATE OR REPLACE TRIGGER emp_trigger AFTER INSERT ON emp FOR EACH ROW -- 행레벨 트리거 DECLARE cnt NUMBER; BEGIN SELECT count(*) INTO cnt FROM emp;
dbms_output.put_line('전체 사원수 : ' || cnt); END; /
SQL> insert into emp (empno, ename) values (3333,'8길동'); insert into emp (empno, ename) values (3333,'8길동') * 1행에 오류: ORA-04091: SCOTT.EMP 테이블이 변경되어 트리거/함수가 볼 수 없습니다. ORA-06512: "SCOTT.EMP_TRIGGER", 4행 ORA-04088: 트리거 'SCOTT.EMP_TRIGGER'의 수행시 오류
2. ORA-04091을 방지하기 위해 명령문 레벨 트리거로 변경
CREATE OR REPLACE TRIGGER emp_trigger AFTER INSERT ON emp -- FOR EACH ROW -- 행레벨 트리거 DECLARE cnt NUMBER; BEGIN SELECT count(*) INTO cnt FROM emp;
dbms_output.put_line('전체 사원수 : ' || cnt); END; /
SQL> insert into emp (empno, ename) values (3333,'8길동'); 전체 사원수 : 17
1 개의 행이 만들어졌습니다. SQL> rollback;
3. pragma autonomous transaction 을 이용 :: DML이 일어나는 세션의 트랜잭션과는 별개로 동작
CREATE OR REPLACE TRIGGER emp_trigger AFTER INSERT ON emp FOR EACH ROW -- 행레벨 트리거 DECLARE PRAGMA AUTONOMOUS_TRANSACTION; cnt NUMBER; BEGIN SELECT count(*) INTO cnt FROM emp;
dbms_output.put_line('전체 사원수 : ' || cnt); END; /
-- 트리거을 일으킨 트랜잭션이 종료되지 않아 입력된 건은 반영되지 않는다. SQL> select count(*) from emp; COUNT(*) ---------- 17 SQL> insert into emp (empno, ename) values (4444,'9길동'); 전체 사원수 : 17
1 개의 행이 만들어졌습니다.
SQL> rollback;
4. Compound Trigger 이용
CREATE OR REPLACE TRIGGER emp_trigger FOR INSERT or UPDATE ON emp COMPOUND TRIGGER
/* Declaration Section*/ cnt NUMBER;
-- 행 레벨 AFTER EACH ROW IS BEGIN dbms_output.put_line('Insert/Update is Completed'); END AFTER EACH ROW;
-- 명령문 레벨 AFTER STATEMENT IS BEGIN SELECT count(*) INTO cnt FROM emp;
dbms_output.put_line('전체 사원수 : ' || cnt); END AFTER STATEMENT;
END emp_trigger; /
SQL> select count(*) from emp;
COUNT(*) ---------- 18
SQL> insert into emp (empno, ename) values (7777,'7길동'); Insert/Update is Completed 전체 사원수 : 19
1 개의 행이 만들어졌습니다. SQL> rollback;
-------------------------------------------------------------------------------- -- Mutating Table Exception 예제 --------------------------------------------------------------------------------
SQL> CREATE TABLE tr_test2 ( id NUMBER(10) primary key, name VARCHAR2(50) );
테이블이 생성되었습니다.
SQL> CREATE SEQUENCE tr_test2_seq;
시퀀스가 생성되었습니다.
SQL> CREATE TABLE tr_test2_log ( id NUMBER(10) primary key, action VARCHAR2(10) NOT NULL, tr_test2_id NUMBER(10), count NUMBER(5), cr_date TIMESTAMP );
테이블이 생성되었습니다.
SQL> ALTER TABLE tr_test2_log ADD ( CONSTRAINT tr_test2_fk FOREIGN KEY (tr_test2_id) REFERENCES tr_test2(id) );
테이블이 변경되었습니다.
SQL> CREATE SEQUENCE tr_test2_log_seq;
시퀀스가 생성되었습니다.
-- 패키지 명세 SQL> CREATE OR REPLACE PACKAGE tr_test2_pkg IS PROCEDURE tr_test2_change (p_id IN tr_test2.id%TYPE, p_action IN VARCHAR2); END tr_test2_pkg; /
패키지가 생성되었습니다.
-- 패키지 바디 SQL> CREATE OR REPLACE PACKAGE BODY tr_test2_pkg IS PROCEDURE tr_test2_change (p_id IN tr_test2.id%TYPE, p_action IN VARCHAR2) IS cnt NUMBER(5) := 0; BEGIN SELECT COUNT(*) INTO cnt FROM tr_test2;
INSERT INTO tr_test2_log VALUES (tr_test2_log_seq.NEXTVAL, p_action, p_id, cnt, SYSTIMESTAMP); END tr_test2_change; END tr_test2_pkg; /
패키지 본문이 생성되었습니다.
SQL> CREATE OR REPLACE TRIGGER tr_test2_trigger AFTER INSERT OR UPDATE ON tr_test2 FOR EACH ROW BEGIN IF inserting THEN tr_test2_pkg.tr_test2_change(p_id => :new.id, p_action => 'INSERT'); ELSE tr_test2_pkg.tr_test2_change(p_id => :new.id, p_action => 'UPDATE'); END IF; END; /
트리거가 생성되었습니다.
-- tr_test2에 after insert 트리거가 동작을 하는데 자기자신 테이블의 레코드건수를 count(*) -- 변하는 값을 참조하므로 4091오류 발생 SQL> INSERT INTO tr_test2 (id, name) VALUES (tr_test2_seq.NEXTVAL, 'OJC'); INSERT INTO tr_test2 (id, name) VALUES (tr_test2_seq.NEXTVAL, 'OJC') * 1행에 오류: ORA-04091: SCOTT.TR_TEST2 테이블이 변경되어 트리거/함수가 볼 수 없습니다. ORA-06512: "SCOTT.TR_TEST2_PKG", 7행 ORA-06512: "SCOTT.TR_TEST2_TRIGGER", 3행 ORA-04088: 트리거 'SCOTT.TR_TEST2_TRIGGER'의 수행시 오류
[해결책]
-- 행 레벨 트리거와 명령문 트리거를 조합하여 해결 -- tr_test2_pkg 패키지에 명령문 트리거에서 호출할 프로시저 추가 -- PL/SQL 데이터 타입중 TABLE TYPE(배열처럼 쓰이는 것)을 이용하여 행 단위 트리거에서 -- 발생하는 데이터를 저장 후 명령문 트리거에서 일괄적으로 삽입하여 해결 SQL> CREATE OR REPLACE PACKAGE tr_test2_pkg AS PROCEDURE tr_test2_change (p_id IN tr_test2.id%TYPE, p_action IN VARCHAR2); PROCEDURE tr_test2_statement_change; END tr_test2_pkg; /
패키지가 생성되었습니다.
SQL> CREATE OR REPLACE PACKAGE BODY tr_test2_pkg AS TYPE type_change_rec IS RECORD ( id tr_test2.id%TYPE, action tr_test2_log.action%TYPE );
TYPE type_change_tab IS TABLE OF type_change_rec; g_change_tab type_change_tab := type_change_tab();
PROCEDURE tr_test2_change (p_id IN tr_test2.id%TYPE, p_action IN VARCHAR2) IS BEGIN g_change_tab.extend; g_change_tab(g_change_tab.last).id := p_id; g_change_tab(g_change_tab.last).action := p_action; END tr_test2_change;
PROCEDURE tr_test2_statement_change IS cnt NUMBER(10); BEGIN FOR i IN g_change_tab.first .. g_change_tab.last LOOP SELECT COUNT(*) INTO cnt FROM tr_test2;
INSERT INTO tr_test2_log VALUES (tr_test2_log_seq.NEXTVAL, g_change_tab(i).action, g_change_tab(i).id, cnt, SYSTIMESTAMP); END LOOP; g_change_tab.delete; END tr_test2_statement_change; END tr_test2_pkg; / 패키지 본문이 생성되었습니다.
-- 새로 추가한 프러시저(tr_test2_statement_change)를 -- 호출하기 위한 명령문 레벨 트리거를 추가하자. SQL> CREATE OR REPLACE TRIGGER tr_test2_trigger2 AFTER INSERT OR UPDATE ON tr_test2 BEGIN tr_test2_pkg.tr_test2_statement_change; END; / 트리거가 생성되었습니다. SQL> INSERT INTO tr_test2 (id, name) VALUES (tr_test2_seq.NEXTVAL, 'OJC'); 1 개의 행이 만들어졌습니다.
------------------------------------------------------------------------------------------ 앞에서 작성한 Mutating Table Exception을 Compound Trigger를 이용해결 ------------------------------------------------------------------------------------------ SQL> drop trigger tr_test2_trigger; 트리거가 삭제되었습니다.
SQL> drop trigger tr_test2_trigger2; 트리거가 삭제되었습니다.
SQL> CREATE OR REPLACE TRIGGER tr_test2_compound_trigger FOR INSERT OR UPDATE ON tr_test2 COMPOUND TRIGGER TYPE type_change_tab IS TABLE OF tr_test2_log%ROWTYPE; g_change_tab type_change_tab := type_change_tab();
AFTER EACH ROW IS BEGIN g_change_tab.extend; g_change_tab(g_change_tab.last).id := tr_test2_log_seq.NEXTVAL; IF INSERTING THEN g_change_tab(g_change_tab.last).action := 'INSERT'; ELSE g_change_tab(g_change_tab.last).action := 'UPDATE'; END IF; g_change_tab(g_change_tab.last).tr_test2_id := :new.id; g_change_tab(g_change_tab.last).cr_date := SYSTIMESTAMP; END AFTER EACH ROW;
AFTER STATEMENT IS BEGIN FOR i IN g_change_tab.first .. g_change_tab.last LOOP SELECT COUNT(*) INTO g_change_tab(i).count FROM tr_test2; END LOOP;
FORALL i IN g_change_tab.first .. g_change_tab.last INSERT INTO tr_test2_log VALUES g_change_tab(i);
g_change_tab.delete; END AFTER STATEMENT;
END tr_test2_compound_trigger; / 트리거가 생성되었습니다.
SQL> INSERT INTO tr_test2 (id, name) VALUES (tr_test2_seq.NEXTVAL, 'OJC'); 1 개의 행이 만들어졌습니다. |
9.5 Trigger Enable/Disable/Drop
n 작성된 트리거는 활성화/비활성화가 가능하다.
n 오라클 11g 이후 트리거를 만들때도 활성화/비활성화 설정이 가능하다.
n Drop Trigger 명령으로 트리거 삭제가 가능하다.
[형식]
ALTER TRIGGER 트리거이름 DISABLE; ALTER TRIGGER 트리거이름 ENABLE; ALTER TABLE 테이블이름 DISABLE ALL TRIGGERS; ALTER TABLE 테이블이름 ENABLE ALL TRIGGERS; DROP TRIGGER 트리거이름; |
SQL> SET SERVEROUTPUT ON SQL> CREATE OR REPLACE TRIGGER tr_emp_test BEFORE INSERT or UPDATE ON emp FOR EACH ROW ENABLE BEGIN DBMS_OUTPUT.put_line('tr_emp_test 실행...'); END; / 트리거가 생성되었습니다.
SQL> insert into emp (empno, ename, sal, deptno) 2 values (7676, '오자바커', 8000, 20);
tr_emp_test 실행...
SQL> CREATE OR REPLACE TRIGGER tr_emp_test BEFORE INSERT or UPDATE ON emp FOR EACH ROW DISABLE BEGIN DBMS_OUTPUT.put_line('tr_emp_test 실행...'); END; / 트리거가 생성되었습니다.
SQL> insert into emp (empno, ename, sal, deptno) values (7677, '오자바커', 6000, 10); 1 개의 행이 만들어졌습니다.
SQL> alter trigger tr_emp_test enable; 트리거가 변경되었습니다.
SQL> insert into emp (empno, ename, sal, deptno) values (7678, '오자바커', 3000, 30); tr_emp_test 실행...
SQL> drop trigger tr_emp_test; 트리거가 삭제되었습니다.
SQL> drop trigger tr_test2_compound_trigger; 트리거가 삭제되었습니다. |
댓글 없음:
댓글 쓰기