트리거를 이용 합계 구하기 (group by) 0 7 2,311

by 옹네 [2011.02.09 12:18:59]



masterTable, detailTable, historySumTable 세개가 있다고 했을때요....

masterTable : pk1, pk2, historyPk
detailTable : pk1, pk2, pk3, pk4, amtCol

historySumTable : historyPk, line_seq (pk), amtSumCol 

하고싶은것은,
detail 테이블의 amtCol 이 바뀔때마다
historySumTable 에 insert 를 두개 하고 싶습니다.

1. historySumTable 원래 있던금액을 line_seq 증가로 amtSumCol * (-1) 처리하여 insert.
2. 변경된 detailTalbe 의 amtCol 합계금액을  line_seq 증가로 amtSumCol 로 insert.

여기에서 1번까지는 되는데 2번 합계금액을 구하는데 있어서 문제가 발생합니다.

에러가 왜 나는지는 알겠는데 이것을 어떻게 구해야 할지 모르겠어요.
(트리거에서 자기 자신을 select 했음 ora-04091)
===========================================================================


CREATE OR REPLACE TRIGGER trauDetailTable
after update
ON detailTable referencing new as new old as old
for each row
declare
wk_hisPk masterTable.historyPk%type;
wk_sum   historyTable.amtSumCol%type;
-- historyPK를 구함
begin
select historyPk
into  wk_hisPk
    from masterTable
    where pk1 = :new.pk1
    and    pk2 = :new.pk2;
exception
    when no_data_found then
    wk_hisPk := '999';
end;

-- 합계금액을 구함 (여기가 문제점이라는것은 알겠는데....합계를 어케 구해야 할지..ㅠ.ㅠ )
begin
select sum(amtCol)
into  wk_sum
    from detailTable
    where pk1 = :new.pk1
    and    pk2 = :new.pk2;
exception
    when no_data_found then
    wk_sum := 0;
end;


-- historySumTable amtSumCol * (-1) 하여 insert
begin
insert into historySumTable
    select 
historyPk,
    (select max(line_seq)+1 from historySumTable where historyPk = wk_hisPk) as line_seq,
   amtSumCol * (-1) as amtSumCol
from historyPk = wk_hisPk
exception
when others then
    raise_application_error(-20010, replace(replace(replace(sqlerrm,'"',''), chr(10),''), chr(13),''));
end;

-- historySumTable amtSumCol에 위에서 구한 합계금액으로 하여 insert
begin
insert into historySumTable
    select 
historyPk,
    (select max(line_seq)+1 from historySumTable where historyPk = wk_hisPk) as line_seq,
    wk_sum as amtSumCol
from historyPk = wk_hisPk; 
exception
when others then
    raise_application_error(-20010, replace(replace(replace(sqlerrm,'"',''), chr(10),''), chr(13),''));
end;

exception
    when others then
   raise_application_error(-20010, sqlerrm);
end trauDetailTable;
by 마농 [2011.02.09 15:06:42]
요런식으로 직접 입력하세요.
amtSumCol - :OLD.amtCol + :NEW.amtCol

단. 이는 기존의 amtSumCol 값이 정확해야 하므로
update 뿐 아니라 insert 및 Delete 에도 트리거를 적용시켜 데이터값을 정확하게 맞춰 줄 필요가 있어 보입니다.

by 옹네 [2011.02.09 15:55:28]
마농님 감사합니다.

update 일때는 마농님 답변처럼 하구
insert 일때는 amtSumCol + :new.amtCol
delete 일때는 amtSumCol - :old.amtCol 하면 될거같아요~

이제사 조금 트리거에 대해 알거같아여...

by 마농 [2011.02.09 16:06:51]
insert 의 경우엔 기존값이 아예 없을 수도 있습니다.
이경우엔 신규로 입력해야겠죠.

by 손님 [2011.03.21 18:47:54]
마농님 님이 만든 이 세가지 테이블의 컬럼들이 어떤 형식들로 만들었는 알려주심 안될까요??
님꺼 보면서 공부할려고 하는데....각테이블들이 어떤형식으로 만들어졌는지 궁금합니다.
masterTable : pk1, pk2, historyPk
detailTable : pk1, pk2, pk3, pk4, amtCol
historySumTable : historyPk, line_seq (pk), amtSumCol

by 마농 [2011.03.22 08:28:23]
음..제가 만든게 아니고 단지 질문에 답했을 뿐입니다...
컬럼형식은 아무거나 선정해서 만들어 보셔도 상관 없을 듯 합니다.
그리고 소스를 따라가면서 보면 대충 간이 오지요.
금액이나 합산하는 항목들은 Number 타입일 거고
wk_hisPk := '999'; 이문장을 보면 wk_hisPk 는 문자형일듯 하고
line_seq 는 Number로 하는게 좋겠죠.

by 오라왕초보 [2011.03.22 12:38:25]
마농님 하나만 더 물어볼께요^^
님이 옹네님한테 답변하신...

요런식으로 직접 입력하세요.
amtSumCol - :OLD.amtCol + :NEW.amtCol

이거를 어디다가 입력하라는 거죠??
워낙 초보라 잘 이해가 않가서요^^;; 답변좀 부탁드립니다^^..

by 마농 [2011.03.22 13:51:07]
음. 공부하시는건 좋은데요.
예제를 오류나서 질문한걸 가지고 공부하시면 힘들죠.
입력은 insert 구문이겠고 해당 컬럼은 함계컬럼이 되겠죠.
변경은 Update 구문이지요.
위에 wk_sum 이라고 변수처리한거에 빨간색 칠해져있는 부분이지요.
insert 하기전에 wk_sum 변수에 미리 입력해 두셔두 되구요.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입