📍비교 요약
| 프로시저 (Procedure) | 트리거 (Trigger) |
| 필요할 때 호출하여 실행 | 이벤트 발생 시 자동으로 실행 |
| 미리 저장된 SQL 문들의 집합으로, 서버에서 실행되는 일종의 함수 |
테이블에 특정 이벤트 (INSERT, UPDATE, DELETE)가 발생 할 때 자동으로 실행 |
| COMMIT, ROLLBACK 등의 트랜잭션 제어 가능 |
COMMIT, ROLLBACK 등의 트랜잭션 제어 제한 |
✅ 트리거 (Trigger)
- 이벤트 발생 시 자동으로 실행
- 테이블에 특정 이벤트 (INSERT, UPDATE, DELETE)가 발생할 때 자동으로 실행되는 코드 블록
- 트리거 내에서 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)
- 필요할 때 호출하여 실행
- 미리 저장된 SQL 문들의 집합으로, 서버에서 실행되는 일종의 함수
- 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 |