DB

[MySQL] CALL 프로시저 내 DML 실행 완전 정복 가이드 ⚙️

인생아 2025. 7. 3. 11:36
반응형

MySQL에서 반복적인 데이터 처리나 로직을 코드로 분리해두고 싶다면, 저장 프로시저(Stored Procedure)를 활용하는 것이 정석이다.
특히 INSERT, UPDATE, DELETE 같은 DML(데이터 조작어)를 프로시저 내에서 실행하면 실무에서 복잡한 비즈니스 로직을 손쉽게 자동화할 수 있다.

🧠 저장 프로시저란?

저장 프로시저(Stored Procedure)는 MySQL 서버에 미리 저장된 SQL 코드 블록이다.
이 코드는 한 번 정의하면 언제든지 CALL 프로시저명() 형태로 실행할 수 있다.

복잡한 반복 로직, 트랜잭션 단위 작업, DML 조합 등을 간결하고 재사용 가능한 형태로 관리할 수 있다는 점에서 매우 유용하다.

✏️ 기본 저장 프로시저 예제: INSERT

간단한 INSERT 예제부터 살펴보자.

DELIMITER $$

CREATE PROCEDURE insert_member(
  IN p_name VARCHAR(50),
  IN p_email VARCHAR(100)
)
BEGIN
  INSERT INTO members (name, email, reg_date)
  VALUES (p_name, p_email, NOW());
END $$

DELIMITER ;

실행하기

CALL insert_member('홍길동', 'hong@example.com');
반응형

🧼 UPDATE와 DELETE도 간단하게

🔁 UPDATE 예제

DELIMITER $$

CREATE PROCEDURE update_email(
  IN p_id INT,
  IN p_email VARCHAR(100)
)
BEGIN
  UPDATE members
  SET email = p_email
  WHERE id = p_id;
END $$

DELIMITER ;
CALL update_email(1, 'newmail@example.com');

🗑️ DELETE 예제

DELIMITER $$

CREATE PROCEDURE delete_member(
  IN p_id INT
)
BEGIN
  DELETE FROM members WHERE id = p_id;
END $$

DELIMITER ;
CALL delete_member(3);

🧾 실전 팁: 트랜잭션 처리도 가능하다

프로시저 내에서 BEGIN ... COMMIT 또는 ROLLBACK을 활용해 트랜잭션 단위로 DML을 묶는 것도 가능하다.

DELIMITER $$

CREATE PROCEDURE process_order(
  IN p_user_id INT,
  IN p_amount DECIMAL(10,2)
)
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
  END;

  START TRANSACTION;

  INSERT INTO orders (user_id, amount, created_at)
  VALUES (p_user_id, p_amount, NOW());

  UPDATE users
  SET balance = balance - p_amount
  WHERE id = p_user_id;

  COMMIT;
END $$

DELIMITER ;

트랜잭션이 정상적으로 완료되지 않으면 자동으로 ROLLBACK되도록 구성할 수 있다.

반응형

🧠 프로시저 내 변수와 조건문

복잡한 조건 분기 처리가 필요한 경우 IF, CASE, WHILE, LOOP 등을 활용할 수 있다.

IF p_amount > 100000 THEN
  SET v_status = '고액';
ELSE
  SET v_status = '일반';
END IF;

프로시저는 사실상 SQL 기반 미니 프로그램이라고 생각하면 된다.

🧩 CALL을 통한 재사용성과 효율성 향상

CALL 프로시저명() 방식으로 반복적인 DML 로직을 여러 번 실행할 수 있기 때문에,
애플리케이션 코드에서 직접 여러 SQL을 나열하는 것보다 유지보수성과 안정성이 크게 향상된다.

📍 주의사항

  • 프로시저 내에서 SELECT는 가능하나, 다중 결과 셋 반환 시 애플리케이션에서 처리 주의
  • DELIMITER 설정을 잊지 말아야 하며, ;가 아닌 $$, // 등의 구분자를 활용해야 함
  • 변수는 DECLARE로 선언하고 BEGIN ... END 블록 안에서 사용

🔗 공식 문서 링크

반응형