Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- this
- 2차원배열 구간합
- 슈더코드
- 백준 1235번
- Bean LifecCycle
- 자바 람다식
- MariaDB Query Log
- SQL
- json
- this와 this() 차이
- map()
- Java
- @AllArgsConstructor
- interrupted()
- pseudo-code
- 생성자
- ajax
- 합배열
- 백준 11659번
- 구간합
- select
- 상속과 참조
- InterruptException
- function test
- jquery
- @NoArgsConstructor
- 백준
- 구간합구하기
- 백준 11660번
- 마리아DB 쿼리 로그
Archives
- Today
- Total
평범한 연구소
[오라클 SQL] 트리거 (Trigger) 본문
트리거
- 특정 조건이 만족하거나 어떤 동작이 수행되면 자동으로 실행
- 예를 들어, DML문이나 DDL문이 실행횔 때 트리거 실행
- CREATE TRIGGER 시스템 권한 있어야 생성 가능
프로시저
- 필요할 때 마다 호출하여 실행 (수동)
- 자주 실행해야 하는 업무 흐름(SQL)을 미리 작성하여 DB 내에 저장
[ 트리거 ]
트리거 생성 권한 부여
- 관리자 계정에서 실행
-- 관리자(sys) 계정: sky계정에게 트리거를 만들 수 있는 권한 부여
GRANT CREATE TRIGGER TO sky;
-- 트리거 목록 확인
SELECT * FROM user_triggers;
-- 트리거 소스 확인
SELECT * FROM user_source;
-- 의존성 확인
SELECT * FROM user_dependencies;
문장 트리거
- 하나의 DML문에서 트리거는 한 번 일어난다
- DELETE FROM table; 문장으로 5개의 레코드가 삭제되어도 트리거는 한 번 실행.
- 테이블에 레코드의 입력, 수정, 삭제 등의 로그 기록
- 트리거 내에서는 자동 커밋된다
- COMMIT; 기술하면 오류 발생
CREATE OR REPLACE TRIGGER testTrigger
AFTER INSERT OR UPDATE OR DELETE ON test
BEGIN
IF INSERTING THEN
INSERT INTO info(num,memo) VALUES (info_seq.NEXTVAL,'레코드 추가');
ELSIF UPDATING THEN
INSERT INTO info(num,memo) VALUES (info_seq.NEXTVAL,'레코드 수정');
ELSIF DELETING THEN
INSERT INTO info(num,memo) VALUES (info_seq.NEXTVAL,'레코드 삭제');
END IF;
END;
/
트리거 생성 : 지정된 시간에만 DML 작업
CREATE OR REPLACE TRIGGER testTrigger2
BEFORE INSERT OR UPDATE OR DELETE ON test
BEGIN
IF TO_CHAR(SYSDATE, 'D') IN (1,7) OR
-- (TO_CHAR(SYSDATE, 'HH24') < 9 OR TO_CHAR(SYSDATE, 'HH24') >18) THEN
(TO_CHAR(SYSDATE, 'HH24') >=14 AND TO_CHAR(SYSDATE, 'HH24') <=15) THEN
RAISE_APPLICATION_ERROR(-20001, '지금은 데이터를 수정할 수 있는 시간이 아닙니다.');
END IF;
END;
/
INSERT INTO test(num, name, content) VALUES (test_seq.NEXTVAL, 'a', 'aaa');
-- 지정된 시간이 아니므로 에러 발생
행 트리거
- DML문에서 조건 만족하는 모든 행에 대하여 트리거 발생
- DELETE FROM table; 문장으로 5개의 레코드가 삭제된 경우, 트리거 5번 실행
- OLD와 NEW 레코드
- 행 트리거에서만 사용 가능
- OLD: UPDATE-수정 전 레코드, DELETE-삭제할 레코드
- NEW: INSERT-추가할 레코드, UPDATE:수정할 레코드
CREATE OR REPLACE FUNCTION fnGrade
(
score NUMBER
)
RETURN NUMBER
IS
result NUMBER(2, 1);
BEGIN
IF score >= 95 THEN result := 4.5;
ELSIF score >= 90 THEN result := 4.0;
ELSIF score >= 85 THEN result := 3.5;
ELSIF score >= 80 THEN result := 3.0;
ELSIF score >= 75 THEN result := 2.5;
ELSIF score >= 70 THEN result := 2.0;
ELSIF score >= 65 THEN result := 1.5;
ELSIF score >= 60 THEN result := 1.0;
ELSE result := 0.0;
END IF;
RETURN result;
END;
/
INSERT 행 트리거 생성
- score1 테이블의 데이터 추가 시 평점을 계산하여 score2 테이블에 데이터 추가
CREATE OR REPLACE TRIGGER scoreInserTrigger
AFTER INSERT ON score1
FOR EACH ROW -- 행트리거
DECLARE
-- 필요한 변수 선언
BEGIN
-- :NEW -> INSERT 하는 레코드를 가지고 있는 레코드
-- 트리거 안에서의 DML은 COMMIT 하지 않는다. 자동 커밋.
INSERT INTO score2(hak, kor, eng, mat) VALUES
(:New.hak, fnGrade(:NEW.kor), fnGrade(:NEW.eng), fnGrade(:NEW.mat));
END;
/
INSERT INTO score1(hak, name, kor, eng, mat) VALUES('111','aaa',80,90,95);
COMMIT;
UPDATE 행 트리거 생성
- score1 테이블의 데이터 수정 시 평점을 계산하여 score2 테이블에 데이터 추가
CREATE OR REPLACE TRIGGER scoreUpdateTrigger
AFTER UPDATE ON score1
FOR EACH ROW
DECLARE
BEGIN
-- :OLD -> UPDATE 전 레코드
-- :NEW -> 새로 UPDATE할 레코드
UPDATE score2 SET kor = fnGrade(:NEW.kor), eng = fnGrade(:NEW.eng),
mat = fnGrade(:NEW.mat)
WHERE hak = :OLD.hak;
END;
/
UPDATE score1 SET kor=100, eng=95, mat=85 WHERE hak='111';
COMMIT;
UPDATE 행 트리거 생성 : 기본키와 참조키 UPDATE
- 부모테이블(score1)의 기본키(hak) 변경되면, 자식테이블(score2)의 참조키(hak)도 변경되도록 UPDATE 트리거 수정
- score1와 score2 테이블은 참조관계. score2에 존재하는 레코드의 참조키를 score1에서 수정하면 에러.
UPDATE score1 SET hak = '100' WHERE hak = '111';
-- 에러
-- 트리거 수정
CREATE OR REPLACE TRIGGER scoreUpdateTrigger
AFTER UPDATE ON score1
FOR EACH ROW
DECLARE
BEGIN
UPDATE score2 SET hak = :NEW.hak,
kor = fnGrade(:NEW.kor), eng = fnGrade(:NEW.eng),
mat = fnGrade(:NEW.mat)
WHERE hak = :OLD.hak;
END;
/
UPDATE score1 SET hak = '100' WHERE hak = '111';
DELETE 행 트리거 생성
- score1 테이블의 데이터 삭제 시 score2 테이블 데이터도 삭제
CREATE OR REPLACE TRIGGER scoreDeleteTrigger
BEFORE DELETE ON score1
FOR EACH ROW
DECLARE
BEGIN
-- :OLD -> DELETE 할 레코드
DELETE FROM score2
WHERE hak = :OLD.hak;
END;
/
DELETE FROM score1 WHERE hak = '100';
'DB|SQL' 카테고리의 다른 글
[myBatis] insert, update 시 NULL 처리 (SQLException: 부적합한 열 유형: 1111) (0) | 2022.11.17 |
---|---|
[Oracle|sql] 시퀀스 마지막 번호(현재값) 알아내기 (0) | 2022.10.26 |
[오라클 SQL] 프로시저 (procedure) (0) | 2022.09.13 |
[오라클 SQL] 시퀀스 (sequence) (0) | 2022.09.13 |
[오라클 SQL] 조인 (Join) (0) | 2022.08.28 |