학생 정보를 저장하는 테이블이 있다고 해보자. 이 테이블에서 새로운 학생이 추가될 때마다 last_modified (레코드가 마지막으로 수정된 날짜) 필드를 자동으로 업데이트해야 해. 이 필드는 변경 사항을 추적하고 데이터를 관리하는 데 중요해.
작동 시나리오는 이래:
- 테이블에 새 레코드가 추가되면
last_modified필드에 자동으로 현재 날짜와 시간이 들어가. AFTER INSERT트리거를 사용할 건데, 이건 데이터가 성공적으로 삽입된 후에 동작해.
트리거용 함수 만들기
먼저 PL/pgSQL 언어로 함수를 만들어야 해. 이 함수가 우리 테이블의 last_modified 필드를 업데이트해줄 거야. 함수는 트리거가 동작하려면 꼭 필요한 요소야. 트리거는 "뭐 할지"만 알려주고, 실제 로직은 함수가 처리하거든.
그럼 테이블부터 만들어보자:
-- students 테이블 만들기
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
age INT NOT NULL,
last_modified TIMESTAMP
);
이제 last_modified 필드를 업데이트하는 함수를 만들어보자:
-- last_modified 업데이트용 함수
CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
-- last_modified 필드에 현재 시간 넣기
NEW.last_modified := NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
이 함수가 뭘 하는지 살펴보자:
CREATE OR REPLACE FUNCTION update_last_modified()—update_last_modified라는 이름의 함수를 만들어. 이미 있으면 덮어써.RETURNS TRIGGER— 이 함수가 트리거에서 쓸 용도라는 걸 알려줘.NEW.last_modified := NOW();—NOW()함수를 써서last_modified필드를 현재 날짜와 시간으로 업데이트해.RETURN NEW;— 업데이트된 레코드를 반환해. AFTER 트리거에서는 이게 필수야.
트리거 만들기
함수를 만들었으니 이제 트리거를 만들어서 students 테이블에 연결해보자. 이렇게 하면 돼:
-- 레코드 삽입 후 트리거 만들기
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();
여기서 하는 일은 이래:
CREATE TRIGGER set_last_modified—set_last_modified라는 이름의 트리거를 만들어.AFTER INSERT— 테이블에 행이 성공적으로 삽입된 후에 트리거가 동작해.ON students— 트리거가students테이블에 연결돼 있어.FOR EACH ROW— 테이블에 새 행이 추가될 때마다 트리거가 실행돼.EXECUTE FUNCTION update_last_modified();— 아까 만든 함수를 호출해.
참고: 트리거 이름(set_last_modified)이나 함수 이름(update_last_modified)은 아무거나 써도 되지만, 네이밍 규칙을 잘 지키면 코드가 더 이해하기 쉬워.
트리거 테스트하기
이제 트리거가 잘 동작하는지 확인해보자. 먼저 students 테이블에 몇 개의 레코드를 추가해볼게:
-- 테이블에 데이터 삽입하기
INSERT INTO students (name, age) VALUES ('이반 이바노프', 20);
INSERT INTO students (name, age) VALUES ('안나 페트로바', 22);
이제 테이블에 뭐가 들어갔는지 확인해보자:
-- 테이블 데이터 보기
SELECT * FROM students;
예상 결과는 대충 이렇게 나올 거야:
| id | name | age | last_modified |
|---|---|---|---|
| 1 | 오토 민 | 20 | 2023-10-10 14:30:45 |
| 2 | 안나 송 | 22 | 2023-10-10 14:31:12 |
last_modified 필드가 각 레코드마다 자동으로 현재 날짜와 시간으로 채워진 걸 볼 수 있어.
발생할 수 있는 오류들
- 오류: "relation does not exist" 트리거 만들 때. 이 오류는
students테이블이 아직 없을 때 나와. 트리거 만들기 전에 테이블이 있는지 꼭 확인해. - 접근 권한 오류. DB 유저에게 함수나 트리거를 만들 권한이 없으면 트리거가 안 만들어져. 유저 권한을 체크해봐.
- 트리거에서 함수 호출 안 함.
EXECUTE FUNCTION update_last_modified()를 빼먹으면 트리거가 원하는 동작을 못 해.
트리거 개선하기: 조건 추가
실제 업무에서는 트리거가 특정 조건에서만 동작하게 하고 싶을 때가 많아. 예를 들어, age 필드가 18보다 작으면 last_modified를 업데이트하고 싶지 않을 수도 있지. 이럴 땐 WHEN 조건을 쓰면 돼:
-- 조건이 있는 트리거 만들기
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
WHEN (NEW.age >= 18)
EXECUTE FUNCTION update_last_modified();
이제 age가 18 이상인 학생만 last_modified 필드가 업데이트돼.
실전에서의 활용
이런 트리거는 실제 프로젝트에서 자주 써. 예시 몇 개 들어볼게:
- 레코드가 마지막으로 수정된 시간을 자동으로 업데이트 (우리가 한 것처럼).
- DB에서 변경 사항을 추적해서 로그 테이블에 기록.
- 데이터 무결성 보장, 예를 들어 연관된 테이블을 체크하고 작업 수행.
- 법적/회사 규정 준수를 위한 데이터 감사.
이런 스킬은 데이터의 정확성과 신뢰성이 중요한 시스템, 예를 들면 은행 시스템, 재고 관리 시스템, CRM 같은 데서 특히 유용해.
GO TO FULL VERSION