MySQL 기준
CALL 프로시저)IN / OUT / INOUT )BEGIN ~ END 내부 SQL 로직 순차 실행OUT / INOUT 결과 반환CREATE PROCEDURE 할 때 문법 검사 및 내부 구조 생성CALL 프로시저명() 으로 실제 실행BEGINDECLARE 변수명 데이터타입 [DEFAULT 기본값];IF 조건 THEN
-- 실행 내용
ELSEIF 조건2 THEN
-- 실행 내용
ELSE
-- 실행 내용
END IF;CASE 변수
WHEN 값1 THEN -- 실행 내용
WHEN 값2 THEN -- 실행 내용
ELSE -- 실행 내용
END CASE;loop_label: LOOP
-- 실행 내용
LEAVE loop_label; -- 루프 종료
END LOOP;WHILE 조건 DO
-- 실행 내용
END WHILE;REPEAT
-- 실행 내용
UNTIL 조건
END REPEAT;START TRANSACTION;
-- 실행 내용
COMMIT;DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
-- 에러 발생 시 실행 로직
END;ENDCALL 프로시저명(매개변수);
➡️ SP 외부에서 트랜잭션으로 묶기
➡️ 정말 필요한 SP만 트랜잭션 포함
➡️ 트랜잭션 여부를 매개변수로 제어
CREATE PROCEDURE TransferPoinsts(
IN p_from_user INT,
IN p_to_user INT,
IN p_point INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
UPDATE users SET point = point - p_point
WHERE id = from_user;
UPDATE users SET point = point + p_point
WHERE id = to_user;
COMMIT;
END;
DECLARE 핸들러종류 HANDLER FOR 핸들러조건
실행 로직;
CONTINUEEXITSQLEXCEPTIONSQLWARNINGNOT FOUNDCREATE PROCEDURE InsertWithWarning()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLWARNING
BEGIN
-- 경고만 기록하고 계속 진행
SET @warning_msg = '경고 발생: 문자열이 잘렸을 수 있음';
END;
INSERT INTO users(name) VALUES ('이름이너무길어요'); -- name 컬럼이 VARCHAR(5)라고 가정
END;
DECLARE 커서명 CURSOR FOR SELECT문;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN 커서명;
FETCH 커서명 INTO 변수1, 변수2, ...;
WHILE NOT done DO
-- 처리 로직
FETCH 커서명 INTO 변수1, 변수2, ...;
END WHILE;
CLOSE 커서명;
CREATE PROCEDURE RewardAllUsers()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE user_id INT;
DECLARE user_name VARCHAR(50);
-- 커서 선언
DECLARE user_cursor CURSOR FOR
SELECT id, name FROM users;
-- FETCH 실패 시 종료 조건
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 커서 오픈
OPEN user_cursor;
read_loop: LOOP
FETCH user_cursor INTO user_id, user_name;
IF done THEN
LEAVE read_loop;
END IF;
-- 처리 로직: 포인트 100씩 추가
UPDATE users SET point = point + 100 WHERE id = user_id;
END LOOP;
-- 커서 종료
CLOSE user_cursor;
END;