CREATE OR REPLACE TRIGGER TRIGGER_TEMP_DAY AFTER INSERT ON TEMP FOR EACH ROW DECLARE vcGET_DATE VARCHAR2(8 BYTE); vcLOC VARCHAR2(5 BYTE); nMAX NUMBER(5, 2); nMIN NUMBER(5, 2); nCNT NUMBER(13); vcGET_DATE_TEMP NUMBER; BEGIN SELECT COUNT(*) INTO vcGET_DATE_TEMP FROM TEMP_DAY WHERE LOC = :NEW.LOC GROUP BY GET_DATE, LOC; SELECT TO_CHAR(GET_TIME, 'YYYYMMDD'), LOC, MAX(TEMP), MIN(TEMP), COUNT(*) INTO vcGET_DATE, vcLOC, nMAX, nMIN, nCNT FROM TEMP WHERE LOC = :NEW.LOC GROUP BY TO_CHAR(GET_TIME, 'YYYYMMDD'), LOC; IF vcGET_DATE_TEMP = 0 THEN INSERT INTO TEMP_DAY (GET_DATE, LOC, MAX, MIN, CNT) VALUES(vcGET_DATE, vcLOC, nMAX, nMIN, nCNT); ELSE UPDATE TEMP_DAY SET GET_DATE = vcGET_DATE ,LOC = vcLOC ,MAX = nMAX ,MIN = nMIN ,CNT = nCNT WHERE LOC = :NEW.LOC; END IF; END;
안녕하세요.
TEMP 테이블에 INSERT가 될때에
TEMP_DAY에 INSERT 또는 UPDATE를 시키는 트리거를 작성해보았는데요.
TEMP 테이블의 GET_TIME을 20140530 식의 일자로 변환하여
TEMP_DAY 테이블의 GET_DATE 에 넣어야하고
그렇게 넣은 날짜값과 위치코드 값을 기준으로 삼아서 하루하루의 온도값에 대한 최대값, 최소값, 수신횟수를 구하는 트리거입니다.
TEMP_DAY테이블에 값이 없으면 INSERT를 시키고, 값이 있으면 UPDATE를 시켜야합니다.
TEMP 테이블
수신일시(GET_TIME) -------------------------- 위치코드(LOC)--------------------------온도(TEMP)
2014-05-30 오후 1:30:22 01 23
2014-05-30 오후 2:30:33 01 6
2014-05-31 오후 3:30:33 01 40
2014-05-31 오후 4:30:22 01 33
2014-05-31 오후 5:22:21 02 22
2014-05-30 오후 2:11:33 02 33
2014-05-30 오후 2:11:34 02 4
-------------------------------------------------------------------------------------------------------------
TEMP_DAY 테이블
수신일자(GET_DATE) ------------위치코드(LOC) ---------최대값(MAX) --------최소값(MIN) ------- 수신횟수(CNT)
20140530 01 23 6 2
20140531 01 40 33 2
20140530 02 33 4 2
20140531 02 22 22 1
이러한 결과값이 나와야하는데 지금 3일째 갈피를 못잡고있습니다...
어디가 잘못된것일까요?
-- temp 테이블에 트리거를 걸때 -- 트리거 안에서 temp 를 참조(Select 등)할 수 없습니다. -- 따라서, Max , Min, Count 는 temp 에서 직접 구하지 마시고 -- temp_day 에 저장된 값과 비교하여 업데이트 하는 방식으로 구현하세요. -- 물론 트리거 생성전에 배치작업으로 temp_day 현행화를 시켜 주세요. CREATE OR REPLACE TRIGGER trigger_temp_day AFTER INSERT ON temp FOR EACH ROW BEGIN MERGE INTO temp_day USING dual ON ( get_date = TO_CHAR(:NEW.get_time, 'yyyymmdd') AND loc = :NEW.loc) WHEN MATCHED THEN UPDATE SET max = GREATEST(max, :NEW.temp) , min = LEAST (min, :NEW.temp) , cnt = cnt + 1 ; WHEN NOT MATCHED THEN INSERT VALUES (TO_CHAR(:NEW.get_time, 'yyyymmdd'), :NEW.loc, :NEW.temp, :NEW.temp, 1) ; END; /
-- 트리거를 적용시키기 전에 최초 한번 temp_day 테이블을 일괄로 갱신시켜 줘야죠. MERGE INTO temp_day a USING ( SELECT TO_CHAR(get_time, 'yyyymmdd') det_date , loc , MAX(temp) max , MIN(temp) min , COUNT(*) cnt FROM temp GROUP BY TO_CHAR(get_time, 'yyyymmdd'), loc ) b ON (a.get_date = b.get_date AND a.loc = b.loc) WHEN MATCHED THEN UPDATE SET max = b.max , min = b.min , cnt = b.cnt ; WHEN NOT MATCHED THEN INSERT VALUES (b.get_date, b.loc, b.max, b.min, b.cnt) ;