트리거 질문드립니다. 0 14 978

by 퇴근하고싶다 [Oracle 기초] [2019.07.12 13:47:31]


안녕하세요 .

조건에 맞게 자동으로 insert를 하고싶습니다.(trigger)

table : staff

직번 이름 직급 성별 생년월일 진급일자
123456 홍길동 사원 880888  
123777 홍길동 주임 880888 20190101
789123 이순신 주임 770777  
789777 이순신 대리 770777 20190201
777987 김유신 과장 660666  
999123 박차장 차장 550555 20170101
888321 안중근 부장 660621  
888123 안중근 전무 660621 20190501

이런 테이블이 있다면...

조건 : staff에 진급일자가 201901이상이고 , 직번,생년월일이 두개인것이 insert나 select 될때마다 staff2에 insert

테이블 : staff2

진급일자 구분번호 이름 생년월일
20190101 123777 홍길동 880888
20190201 789777 이순신 770777
20190501 888123 안중근 660621
       
       
       
       
       

감사합니다.

by 러드 [2019.07.12 13:55:22]

머칠전 질문을 트리거만 추가해서 다시 올리셨네요...

전에 질문에 글쓴사람에 대한 "알겠다는" "해보겠다는" 답글도 없이...

트리고도 전글 처리 쿼리로 진행하시면 됩니다.


by 퇴근하고싶다 [2019.07.12 14:38:49]

앗 제가 질문을 잘못올려서 다시 올렸습니다. 죄송합니다.


by 마농 [2019.07.12 13:58:13]

단순 트리거로 구현하기 힘든 부분입니다.
이유 : 트리거 내에서 해당 테이블을 참조해야 하므로 오류 발생.
복합트리거로 구성해야 하는데 이게 난이도가 좀 높습니다.
이렇게까지 해야 하는지 의문입니다.
꼭 트리거로 해야 하나요?
프로그램 로직으로 푸는게 좋을 듯 합니다.
입력값 사전 체크하여 조건에 맞으면? 두군데 테이블에 Insert 하는 방식.


by 퇴근하고싶다 [2019.07.12 15:08:56]

답변 감사합니다.

동시에 두군데 테이블에 insert가 아닌..

staff 테이블은 다른 프로그램로직에 의해 insert나 update가 되고 있습니다.

이러한 staff 테이블에 insert나 update가 될때 주어진 조건에 맞으면(staff 에 진급일자가 201901이상이고 , 직번,생년월일이 두개)

트리거에 의해 staff2에 자동으로 insert를 하고싶습니다.

staff 테이블에 데이터가 들어올때 마다 찾아서 staff2에 insert를 할수가 없어서 ㅠㅠ


by 마농 [2019.07.12 14:18:39]
INSERT ALL
WHEN 1=1 THEN
     INTO staff(직번, 이름, 직급, 성별, 생년월일, 진급일자)
     VALUES    (직번, 이름, 직급, 성별, 생년월일, 진급일자)
WHEN gb = 1 THEN
     INTO staff2(진급일자, 구분번호, 이름, 생년월일)
     VALUES     (진급일자, 직번    , 이름, 생년월일)
SELECT a.직번
     , a.이름
     , a.직급
     , a.성별
     , a.생년월일
     , a.진급일자
     , NVL2(b.이름, 1, 0) gb
  FROM (-- 신규 입력 대상 값 --
        SELECT '123777'   직번
             , '홍길동'   이름
             , '주임'     직급
             , '남'       성별
             , '880888'   생년월일
             , '20190101' 진급일자
          FROM dual
        ) a
  LEFT OUTER JOIN staff b
    ON a.이름     = b.이름
   AND a.생년월일 = b.생년월일
   AND a.진급일자 >= '20190101'
 WHERE ROWNUM = 1
;

 


by 마농 [2019.07.12 15:43:13]

행단위 트리거에서는 해당 테이블을 참조할 수 없습니다. (뮤테이팅에러 발생)
에러 해결방법은 문장단위와 행단위를 넘나들며 동작하는 복합 트리거를 작성하셔야 합니다.
뮤테이팅 에러 해결방법 찾아보세요.
http://gurubee.net/article/54396
http://gurubee.net/article/61280
http://gurubee.net/article/53504
꼭 실시간으로 반영되어야 하는 것인지? 배치작업 형태로 작업 해도 되는지?


by 퇴근하고싶다 [2019.07.12 16:02:47]

답변감사합니다..!

제가 트리거에 대한 개념이 부족하네요..

실시간으로 반영을 하게된다면 뮤테이팅에러가 발생된다느건가요..?

배치작업을 통하면 어떻게 해야하는지.....ㅠ.....


by 마농 [2019.07.12 16:31:15]

1. 트리거는
(실시간 반영 = 에러) 라는게 아니라
(트리거에서 자기참조 = 에러)라는 거구요.
트리거로 에러 회피하는 방법이 상당히 복잡하고 어려우니
다른 방법을 생각해 보라고 한 것입니다.
트리거로 꼭 하고 싶으면 하면 됩니다.
2. 배치 작업은
원하는 로직 동작하는 프로시져 작성하고
해당 프로시져를 job 이나 schedule 에 등록하여 주기적으로 돌려주시면 됩니다.


by 퇴근하고싶다 [2019.07.15 09:15:44]

답변감사합니다..!

create or replace trigger emp_no
after insert or update on staff
--for each row
--declare
begin insert into staff2 (진급일자,구분번호,이름,생년월일)
select 직번,
        이름,
       직급,
        성별,
        생년월일,
        진급일자
from staff2
where 생년월일 in(select 생년월일
                     from staff
                     group by 생년월일
                     having count(*) >1)               
and  진급일자 >= 201901
order by 생년월일,진급일자;
end;

이렇게 트리거를 생성해보았는데 선생님 말씀처럼 안되네요...ㅠ 

키값을 입력안해서 그런지... staff에 insert가 될때마다 계속 중복허용되면서 staff2에 insert가 되네요....

감사합니다..!

 


by 마농 [2019.07.15 10:15:05]

지금 작성하신 로직은 전체 자료에 대한 1회성 로직(최초 1회 수행)입니다.
신규자료 insert 될 때마다 체크하는 로직이 아닙니다.
1회성 로직을 트리거로 반복해 돌리면 중복 될 수 밖에 없습니다.


by 퇴근하고싶다 [2019.07.15 13:42:53]

신규자료를 insert 될 때마다 체크하려면 뮤테이팅오류가 발생하네요 ㅠㅠ

감사합니다..ㅠㅠ


by 퇴근하고싶다 [2019.07.15 17:26:36]

create or replace trigger emp_no
after insert or update on staff
for each row
when(new.진급일자>=201901)
 begin
insert into staff2 (진급일자,직번,주민등록번호,이름,성별,직급)
values(:new.진급일자,:new.직번, :new.주민등록번호,:new.이름,:new.성별,:new.직급);
end;

이렇게 트리거 자체에 조건을 거니깐 되는거 같습니다...!

 


by 마농 [2019.07.16 02:04:52]

기존 자료가 있는지 체크하는 로직이 없으니 뮤테이팅 에러가 없죠.


by 퇴근하고싶다 [2019.07.16 09:35:06]

create or replace trigger emp_no
 after insert or update on staff
 for each row
 when(new.진급일자>=201901 and )  --이부분에
/* -- (select 생년월일
                     from staff
                      group by 생년월일
                     having count(*) >1)

*/ --- 추가 할려면 when절에 바로 넣을수가 없나요...?
 begin 
 insert into staff2 (진급일자,직번,주민등록번호,이름,성별,직급)
values(:new.진급일자,:new.직번, :new.주민등록번호,:new.이름,:new.성별,:new.직급);
end;

when 절에 위와같은 조건을 추가하면 뮤테이팅 에러가 발생하나요?ㅠ

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