Database/DBMS

[DBMS] 트리거(trigger) / 프로시저(procedure)

오류나면꽥꽥 2025. 7. 15. 17:17

📍비교 요약

프로시저 (Procedure) 트리거 (Trigger)
필요할 때 호출하여 실행 이벤트 발생 시 자동으로 실행
미리 저장된 SQL 문들의 집합으로,
서버에서 실행되는 일종의 함수
테이블에 특정 이벤트 
(INSERT, UPDATE, DELETE)가 발생
할 때 자동으로 실행
COMMIT, ROLLBACK 등의
트랜잭션 제어 가능
COMMIT, ROLLBACK 등의
트랜잭션 제어 제한

 

 

 

 

 

 

✅ 트리거 (Trigger)

  1. 이벤트 발생 시 자동으로 실행
  2. 테이블에 특정 이벤트 (INSERT, UPDATE, DELETE)가 발생할 때 자동으로 실행되는 코드 블록
  3. 트리거 내에서 COMMIT, ROLLBACK 등의 트랜잭션 제어는 제한

 

 

기본문법)

CREATE TRIGGER 트리거_이름
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 테이블_이름
FOR EACH ROW

BEGIN
   -- 실행할 SQL 문
END;
  • BEFORE: 이벤트 전에 실행 ( 미리 데이터를 확인 가능할 때 )
  • AFTER: 이벤트 후에 실행
  • FOR EACH ROW: 이벤트가 발생한 각 행마다 실행됨

 

ex)

CREATE TRIGGER log_employee_insert
AFTER INSERT ON employees
FOR EACH ROW

BEGIN
    INSERT INTO employee_log (emp_name, action_time, action_type)
    VALUES (NEW.name, NOW(), 'INSERT');
END;

 

CREATE TABLE employee_backup (
    id INT,
    name VARCHAR(100),
    position VARCHAR(100),
    backup_time DATETIME
);

CREATE TRIGGER backup_before_update
BEFORE UPDATE ON employees
FOR EACH ROW

BEGIN
    INSERT INTO employee_backup (id, name, position, backup_time)
    VALUES (OLD.id, OLD.name, OLD.position, NOW());
END;
  • OLD: 기존 행의 값
  • NEW: 바뀐 행의 값
  OLD NEW
INSERT X O
UPDATE O O
DELETE O X

 

 

 

 

 

 

 

 

 

✅ 프로시저 (Procedure)

  1. 필요할 때 호출하여 실행
  2. 미리 저장된 SQL 문들의 집합으로, 서버에서 실행되는 일종의 함수
  3. COMMIT, ROLLBACK 등의 트랜잭션 제어가 가능

 

 

기본문법)

DELIMITER //

CREATE PROCEDURE GetEmployeeByID(IN empID INT)
BEGIN
    SELECT * FROM Employees WHERE EmployeeID = empID;
END //

DELIMITER ;

 

  • DELIMITER //: 명령어 구분 기호를 //로 바꿈
  • END //: 이걸 만나야 프로시저가 끝났다고 인식함
  • DELIMITER ;: 다시 원래대로 세미콜론(;)으로 돌려놓음

 

 

 

❗ DELIMITER를 사용하는 이유

더보기
더보기
BEGIN
   SELECT ...;
   UPDATE ...;
END;

⚠ 여기서 문제가 생겨요.
SQL 인터프리터가 ;를 만나면 "명령이 끝났다"고 인식하기 때문에,

BEGIN ... END 전체를 하나의 명령으로 인식하지 못함.

 

= DELIMITER를 사용하여 프로시저가 ; 대신 다른 기호로 인식

 

 

ex)

DELIMITER //

CREATE PROCEDURE GetEmployeeInfo(IN empName VARCHAR(50))
BEGIN
    SELECT * FROM employees WHERE name = empName;
END //

DELIMITER ;

 

 

 

조건문 문법)

IF 조건 THEN
	실행할 문장;
ELSE
	실행할 문장;
END IF;

 

 

 

반복문 문법)

LOOP
	실행할 문장;
	EXIT WHEN 조건;
End LOOP;

 

 

 

 

 

📍 프로시저 호출은 어디서?

 

[ 클라이언트 or 애플리케이션 ]
                      ↓  (CALL 명령으로 요청) 
[ 데이터베이스 서버 (MySQL 등) ]
      → 여기서 프로시저가 실행됨

 

호출주체 예시 설명
사용자 (터미널) CALL GetUserInfo(1); 직접 입력
GUI 툴 SQL 에디터에 CALL 입력 클릭으로 실행
애플리케이션 Python, Java 등에서 DB 드라이버로 CALL 동적 호출
서버 내부 (자동화) 트리거나 이벤트로 자동 CALL 사용자 개입 없음

 

 

1️⃣ 사용자 (터미널/CLI에서 직접 호출)

$ mysql -u root -p

로그인 후: 사용자는 직접 CALL 명령어를 입력해서 실행

USE your_database;
CALL GetUserInfo(1);

 

 

 

2️️ 클라이언트 툴 (MySQL Workbench, DBeaver, phpMyAdmin 등)

CALL GetUserInfo(1);
  • SQL 창에 위 코드를 작성하고 "실행 버튼" 클릭하면 호출됨
  • 결과는 아래 테이블로 표시됨

 

 

3️⃣ 애플리케이션 코드에서 호출

ex) Java (JDBC 사용)

Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
CallableStatement stmt = conn.prepareCall("{ call GetUserInfo(?) }");
stmt.setInt(1, 1);
ResultSet rs = stmt.executeQuery();

while (rs.next()) {
    System.out.println("사용자 이름: " + rs.getString("username"));
}

 

ex) Python (mysql-connector 사용)

import mysql.connector

conn = mysql.connector.connect(
    host="localhost",
    user="root",
    password="yourpass",
    database="yourdb"
)

cursor = conn.cursor()
cursor.callproc("GetUserInfo", [1])

for result in cursor.stored_results():
    print(result.fetchall())

cursor.close()
conn.close()
  • 애플리케이션이 서버에 SQL을 보내고, 서버는 프로시저를 실행

 

 

4️⃣ 트리거나 이벤트 스케줄러에서 내부 호출 (DB 서버에서 자동 실행)

ex) 매일 1시에 프로시저 자동 실행

CREATE EVENT IF NOT EXISTS DailyUserCheck
ON SCHEDULE EVERY 1 DAY STARTS '2025-07-30 01:00:00'
DO
   CALL GetUserInfo(1);
  • 서버 자체에서 CALL을 실행
    (MySQL에서 EVENT SCHEDULER가 활성화되어 있어야 함)

'Database > DBMS' 카테고리의 다른 글

[DBMS] 서브 쿼리  (0) 2024.02.16
[DBMS] JDBC에서 Query 사용  (1) 2024.02.15
[DBMS] JDBC 연결방법  (0) 2024.02.15
[DBMS] JDBC  (0) 2024.02.14