트리거 0 11 2,809

by 불기둥 [Oracle 기초] 트리거 [2023.04.04 13:41:41]


트리거 생성시 소스테이블, 타겟 테이블 이용하는데.... 소스테이블 대신 소스테이블을 이용해 만든 view 테이블로 타겟테이블에 데이터를 넣을 수 있나요?  간단히 말하면 View 테이블로 trigger 가능한가요? 이해를 위한 간단한 샘플좀..^^

by 마농 [2023.04.04 13:55:25]

트리거 걸리는 테이블 t1 과 트리거에 따라 갱신되는 테이블 t2 가 있다고 가정했을 때
트리거 t1 > t2 로 간략하게 표현해보면
트리거 v1 > t2 를 하고 싶다는 거군요?
1. v1 이 갱신 가능 뷰인 경우 : t1 > t2 트리거를 걸면 v1 갱신 시 자동으로 해당 트리거 탑니다. (v1 > t1 > t2)
2. v1 이 갱신 불가능 뷰인 경우 : v1 에 직접 트리거를 걸 수 있습니다.(instead of trigger) (v1 > t2)


by 불기둥 [2023.04.04 14:04:18]

갱신 가능? 불가능?  그리고 한가지 질문더... view 테이블은 타겟테이블과 동일한 칼럼명과 타입으로  만들려고 합니다. 어떻게 생성되어야 되나요? 소스테이블의 특정조건으로 view 테이블을 만드는데... 타겟테이블의 동일한 칼럼명과 타입으로...


by 마농 [2023.04.04 14:12:31]

1. 뷰를 만들면 갱신 가능/불가능 여부가 결정됩니다.
- 몇가지 제약사항을 만족한다면 갱신이 가능합니다.
- 복잡한 뷰나 이상한 함수 사용한 뷰가 아니라면? 단순 조회뷰라면? 갱신 가능합니다.
- 뷰에 작접 인서트/업데이트/딜리트가 가능하다는 말이죠.
- 뷰에 대한 갱신은 원본테이블에 직접적으로 가해집니다.
- 따라서 원본 테이블에 트리거를 걸면 됩니다.
- http://gurubee.net/lecture/1036
2. 타겟 테이블과 동일한 모양의 뷰를 만들고 싶다면?
- 원하는 결과를 출력하는 SELECT 구문 그대로 만들면 됩니다.
- 다만, 컬럼을 가공한다면 가공된 컬럼은 갱신이 안되겠지요?


by 불기둥 [2023.04.04 15:48:22]

ST: 소스테이블, TT : 타겟테이블, VT: select null order, null order_name from ST where si_type ='aa' 이런 구조로 만든 view 테이블. 

 

 

 

 

 

 

 

Create or ...

After insert or update oron delete on VT

이런방식으로  view 테이블로 트리거를 생성하려는데 ora-25001: 이 유형의 뷰에는 이 트리거 유형을 생성할 수 없습니다 오류 뜨네요. View 만들때 null 로 해서 인가요?  아직 매핑을 알수 없어서... 


by 마농 [2023.04.04 16:27:19]

해당 뷰에는 소스테이블의 컬럼이 하나도 없네요? 이런 뷰가 의미가 있는지?
제 설명을 다시 한번 정독해 주세요.


by 불기둥 [2023.04.04 21:17:46]

ST: 소스테이블(ENO,ENAME,ETYPE), TT : 타겟테이블 (TNO, TNAME), VT: select ENO AS TNO, ENAME AS TNAME from ST where ETYPE='aa' 이런 구조로 만든 view 테이블. 

 

아래는 일반적인 Trigger 형태 여기서 ST를 사용하지 않고 VT를 사용하고 싶습니다.

CREATE OR REPLACE TRIGGER TRG_TEST
AFTER INSERT OR UPDATE OR DELETE ON ST
FOR EACH ROW
        DECLARE 
        EROLE VARCHAR2(100) := '';
    BEGIN    
    IF INSERTING THEN
        INSERT INTO TT (TNO, TNAME)
        SELECT :NEW.ENO, :NEW.ENAME
        FROM DUAL
     ELSIF UPDATING THEN
        UPDATE TT
        SET TNAME= :NEW.ENAME
        WHERE TNO= :OLD.ENO;
    END IF;
 END TRG_TEST;  

 

=========================

아래 처럼 ST -> VT 로 변경시 ora-25001: 이 유형의 뷰에는 이 트리거 유형을 생성할 수 없습니다 오류나는거 같습니다.

CREATE OR REPLACE TRIGGER TRG_TEST
AFTER INSERT OR UPDATE OR DELETE ON VT
FOR EACH ROW
        DECLARE 
        EROLE VARCHAR2(100) := '';
    BEGIN    
    IF INSERTING THEN
        INSERT INTO TT (TNO, TNAME)
        SELECT :NEW.ENO, :NEW.ENAME
        FROM DUAL
     ELSIF UPDATING THEN
        UPDATE TT
        SET TNAME= :NEW.ENAME
        WHERE TNO= :OLD.ENO;
    END IF;
 END TRG_TEST;  

==========================================

ST는 그대로 사용하고 from dual 를 from VT 형태로 사용해야 되나요?

CREATE OR REPLACE TRIGGER TRG_TEST
AFTER INSERT OR UPDATE OR DELETE ON ST
FOR EACH ROW
        DECLARE 
        EROLE VARCHAR2(100) := '';
    BEGIN    
    IF INSERTING THEN
        INSERT INTO TT (TNO, TNAME)
        SELECT ENO,ENAME
        FROM VT WHERE TNO = :NEW
     ELSIF UPDATING THEN
        UPDATE TT
        SET TNAME= :NEW.ENAME
        WHERE TNO= (SELECT TNO FROM VT FROM TNO = :OLD.ENO);
    END IF;
 END TRG_TEST;  

=========================================

예가 잘 만들어졌는지... ㅜ.ㅜ   view 테이블을 이용해서 Target에 데이터를 넣을려고 하는겁니다.  어떤 작업을 하려고 하는지 이해가 되시면 샘플 Trigger 하나 만들어 주시면 감사하겠습니다.

IF INSERTING THEN  

ELSIF UPDATING THEN 

ELSIF  DELETING THEN 구문도 필요합니다.


by 마농 [2023.04.05 08:06:02]

1. 이미 첫 댓글에서 답은 드렸습니다. -> INSTEAD OF TRIGGER
- 다만, 굳이 왜 이걸 써야 하는지는 의문입니다.
- 납득할만한 이유나 목적이 있나요? 굳이 왜?
2. 추가로 insert 구문에서
- Select From dual 은 불필요해 보입니다.
- values 구문 이용하세요.


by 불기둥 [2023.04.05 09:19:34]

INSTEAD OF TRIGGER 를 사용하니 VT 사용해도 오류는 없네요. VT를 사용하는것은 ST에는 'aa','bb','cc' 형태의 데이터가 입력된다고 할때 'aa' 가  입력될때만 trigger를 이용해 TT에 넣고 싶기 때문입니다. VT대신 ST를 사용하고 Where 졸에서 'aa' 인것을 구분해야 되나요?


by 마농 [2023.04.05 09:29:04]

IF 문으로 제어하면 됩니다.


by 마농 [2023.04.05 13:26:08]

aa 에 대한 뷰를 만들고 이 뷰는 특정 사용자에게만 권한을 주고
WITH CHECK OPTION 으로 뷰를 만들어야 할 듯 합니다.
그 사용자가 이 뷰에 변경을 가할 때만 트리거가 동작하게 하려는 건가요?
이 뷰에 트리거를 건다면?
만약 뷰를 통한 입력이 아닌 테이블에 직접 aa 를 입력하는 경우에는 트리거가 동작하지 않을 것입니다.

즉, 특정 유저가 해당 뷰를 이용해 갱신한 내용만 기록한다?
이게 맞다면 그 생각대로 진행하시면 됩니다.

그게 아니라면?
그냥 aa 에 대한 변경기록을 하기만 하면 되는 거라면?
테이블에 트리거 거는게 맞습니다.


by 마농 [2023.04.05 13:34:17]

한가지 또 있습니다.
instead of trigger 로 만들엇을 때
뷰에 대한 입력 변경은 트리거 로직 안에서만 끝난다는 것입니다.
즉, 타겟 테이블에 입력하는 로직만 있다면 타겟 테이블에만 들어갈 것입니다.
소스테이블에 반영이 안된다는 것이죠.
소스테이블에도 반영을 시키려면 소스테이블 반영 로직도 같이 있어야 합니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입