변경된 값에 대해서만 트리거
테이블에 3개의 레코드가 있다고 가정합니다: orig_tab
---------------------------------------------
| PK | Name | Address | Postal Code |
---------------------------------------------
| 1 | AA | Street1 | 11111 |
| 2 | BB | Street2 | 22222 |
| 3 | CC | Street3 | 33333 |
---------------------------------------------
이제 데이터가 변경되었습니다.
---------------------------------------------
| PK | Name | Address | Postal Code |
---------------------------------------------
| 1 | AA | Street1 | 11111 |
| 2 | BB | Street2 | 44444 |
| 3 | CC | Dtreet7 | 33333 |
---------------------------------------------
고객이 원하는 것은 업데이트 레코드와 업데이트된 열(네, 말이 안 되는 것은 알지만 1970년대의 오래된 시스템을 사용하고 로그 등을 수행하기를 원합니다.)입니다.따라서 보고 테이블은 다음과 같아야 합니다.
---------------------------------------------
| PK | Name | Address | Postal Code |
---------------------------------------------
| 2 | | | 44444 |
| 3 | | Dtreet7 | |
---------------------------------------------
제가 시도한 것은 다음과 같습니다.
CREATE OR REPLACE TRIGGER vr_reporting_trigger
AFTER UPDATE ON orig_tab
FOR EACH ROW
BEGIN
IF inserting THEN
INSERT INTO rep_tab(pk, name, address, code)
SELECT :new.pk, :new.name, :new.address, :new,code FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM rep_tab WHERE pk = :new.pk);
UPDATE rep_tab t SET t.name = :new.name, t.address = :new.address, t.code = :new.code
WHERE t.pk = :new.pk;
ELSIF updating THEN
IF :new.pk <> :old.pk THEN
UPDATE rep_tab t
SET t.name = :new.name, t.address = :new.address, t.code =: new.code
WHERE t.pk = :old.pk ;
END IF;
MERGE INTO rep_tab d
USING DUAL ON (d.pk = :old.pk)
WHEN MATCHED THEN
UPDATE SET d.name = :new.name, d.address = :new.address, d.code =: new.code
WHEN NOT MATCHED THEN
INSERT (d.pk,d.name, d.address, d.code) VALUES (:new.pk,:new.name, new.address, new.code);
END IF;
END;
이 솔루션을 사용하면 다음과 같은 이점을 얻을 수 있습니다.
---------------------------------------------
| PK | Name | Address | Postal Code |
---------------------------------------------
| 2 | BB | Street2 | 44444 |
| 3 | CC | Dtreet7 | 33333 |
---------------------------------------------
나는 명세서를 업데이트할 때 조항 삽입 부분 어딘가에 있다는 것을 알고 있지만 내 요구 사항에 따라 이 조항을 변경하는 방법을 알 수 없습니다.제안할 것이 있습니까?
잘 부탁드립니다.
다음이 필요합니다.
UPDATE 트리거에서 열 이름을 UPDATING 조건부 술어로 지정하여 명명된 열이 업데이트되는지 여부를 확인할 수 있습니다.예를 들어 트리거가 다음과 같이 정의된다고 가정합니다.
CREATE OR REPLACE TRIGGER ...
... UPDATE OF Sal, Comm ON Emp_tab ...
BEGIN
... IF UPDATING ('SAL') THEN ... END IF;
END;
변경된 값에 대해서만 트리거합니다.
예를 들어(만 해당)NOT NULL
support) (NULL을 가진 비교 연산자는 항상 FALSE를 반환함):
CREATE OR REPLACE TRIGGER trigger_department_update
BEFORE UPDATE OF
department_id,
cluster_id,
division_id,
macroregion_id,
address,
email
ON cl_department
FOR EACH ROW
BEGIN
IF (
:new.department_id != :old.department_id
OR :new.cluster_id != :old.cluster_id
OR :new.division_id != :old.division_id
OR :new.macroregion_id != :old.macroregion_id
OR :new.address != :old.address
OR :new.email != :old.email
)
THEN :new.update_date := CURRENT_TIMESTAMP;
END IF;
END;
NULL 지원의 경우(이 게시물 아래 댓글의 @Oleg 덕분) (@Chris Bandy의 답변에 감사드립니다):
CREATE OR REPLACE TRIGGER trigger_department_update
BEFORE UPDATE OF
department_id,
cluster_id,
division_id,
macroregion_id,
address,
email
ON cl_department
FOR EACH ROW
BEGIN
IF (
((:new.department_id <> :old.department_id OR :new.department_id IS NULL OR :old.department_id IS NULL) AND NOT (:new.department_id IS NULL AND :old.department_id IS NULL))
OR ((:new.cluster_id <> :old.cluster_id OR :new.cluster_id IS NULL OR :old.cluster_id IS NULL) AND NOT (:new.cluster_id IS NULL AND :old.cluster_id IS NULL))
OR ((:new.division_id <> :old.division_id OR :new.division_id IS NULL OR :old.division_id IS NULL) AND NOT (:new.division_id IS NULL AND :old.division_id IS NULL))
OR ((:new.macroregion_id <> :old.macroregion_id OR :new.macroregion_id IS NULL OR :old.macroregion_id IS NULL) AND NOT (:new.macroregion_id IS NULL AND :old.macroregion_id IS NULL))
OR ((:new.address <> :old.address OR :new.address IS NULL OR :old.address IS NULL) AND NOT (:new.address IS NULL AND :old.address IS NULL))
OR ((:new.email <> :old.email OR :new.email IS NULL OR :old.email IS NULL) AND NOT (:new.email IS NULL AND :old.email IS NULL))
)
THEN :new.update_date := CURRENT_TIMESTAMP;
END IF;
END;
null을 처리합니다.
... nvl(to_char(:new.department_id,' ') <> nvl(to_char(:old.department_id,' ') OR ...
언급URL : https://stackoverflow.com/questions/11201045/trigger-for-only-changed-values
'programing' 카테고리의 다른 글
스프링 컨트롤러와 끝점의 차이 (0) | 2023.07.22 |
---|---|
변수를 int 대 round() 함수에 사용 (0) | 2023.07.22 |
SQL 알고리즘 정렬기 (0) | 2023.07.22 |
단순한 파이썬 웹 서비스를 만드는 가장 좋은 방법 (0) | 2023.07.22 |
효율적인 순환 버퍼? (0) | 2023.07.22 |