FK가 잡혀있을 때, 키 값이 업데이트가 되지 않는 경우가 존재한다.
학생 테이블 |
---|
학생ID |
학생 나이 |
학교 ID |
.. |
학교 테이블 |
---|
학교 ID |
.. |
예를 들어 테이블이 이렇게 존재한다고 하자. (어디까지나 예이다...)
테이블이 존재함과 더불어 이미 데이터들이 들어있으며, 학생테이블 학교ID 와 학교테이블 학교ID는 FK 관계이며 제약조건(CONSTRAINT)까지 걸려있다.
그런데 중간에 학교 ID 채번룰이 바뀌었다. 따라서 바뀐채번룰에 맞게 기존 데이터를 변경하려고 한다.
학생 테이블에 UPDATE 문을 날렸다.
UPDATE 학생테이블
SET OLD_학교ID = NEW_학교ID
WHERE 학교ID = OLD_학교ID
오류가 난다. CONSTRAINT에 위배가 된다고 한다.
그렇다면 학교 테이블부터 변경해보자 학교테이블에 UPDATE 문을 날렸다.
UPDATE 학생테이블
SET OLD_학교ID = NEW_학교ID
WHERE 학교ID = OLD_학교ID
오류
가 난다. 역시 CONSTRAINT에 위배가 된다고 한다.
무결성 제약조건(CONSTRAINT KEY NAME)이 위배되었습니다 - 자식 레코드가 발견되었습니다. OR 부모테이블에 키값이 존재하지 않습니다(메시지가 정확하지 않을 수 있음)
어떻게 해야할까.. 우리는 테이블 하나의 컬럼이 FK에 걸려있을 때, FK가 걸려있는 컬럼이 수정될 때 FK도 자동적으로 변경되기를 원한다.
삭제할 경우 ON DELETE CASCADE를 사용할 수 있다. 하지만 업데이트시에 오라클에서는 ON UPDATE CASCADE를 지원하지 않는다.
따라서 구글링 결과 한가지 해결법으로 업데이트 쿼리문을 트리거를 생성해서 사용해야한다는 것을 알게 되었다.
그렇다면 TRIGGER는 무엇일까?
INSERT, UPDATE, DELETE문이 TABLE에 대해 행해질 때 묵시적으로 수행되는 PROCEDURE 이다.
트리거는 TABLE과는 별도로 DATABASE에 저장된다.
행 트리거 : 컬럼의 각각 행의 데이터 행 변화가 생길때마다 실행되며, 그 데이터 행의 실제값을 제어할 수 있다.
문장 트리거 : 트리거 사건에 의해 단 한번 실행되며, 컬럼의 각 데이터 행을 제어할 수 없다.
트리거 문법
CREATE [OR REPLACE] TRIGGER trigger_name
BEFORE | AFTER
trigger_event ON table_name
[FOR EACH ROW]
[WHEN(condition)]
PL/SQL block
CREATOR OR REPLCAE TRIGGER TRG_SCHOOL_ID_UPDATE
AFTER UPDATE OF 학교ID ON 학교테이블 FOR EACH ROW
BEGIN
UPDATE 학생테이블
SET 학교ID = :NEW.학교ID
WHERE 학교ID = :OLD.학교ID
END;
- BEFORE : INSERT, UPDATE, DELETE문이 실행되기 전에 트리거 실행
- AFTER : INSERT, UPDATE, DELETE문이 실행된 후 트리거 실행
- trigger_event : INSERT, UPDATE, DELETE 중에서 한 개 이상 올 수 있다.
- FOR EACH ROW : 이 옵션이 있으면 행 트리거가 된다.
이렇게 트리거를 생성한 후 UPDATE문을 실행하게 되면 트리거가 자동으로 타게되어 학생테이블의 학교 ID까지 업데이트시켜주게 된다.
(부모테이블에 UPDATE시 트리거를 걸어야 한다. 부모 UPDATE -> 자식 UPDATE)
트리거 삭제하기
DROP TRIGGER trigger_name[;]
'Life > Today I Learned' 카테고리의 다른 글
2019/05/08 (0) | 2019.05.08 |
---|---|
[오라클] Constraint 제한 풀기(제약조건 비활성화) (0) | 2019.05.08 |
2019/05/03 (0) | 2019.05.03 |
2019/04/29 (0) | 2019.04.29 |
2019/04/24 (0) | 2019.04.24 |