저장 프로시저 (Stored Procedure)

한눈에 보기

저장 프로시저는 SQL 묶음을 데이터베이스에 저장해 두고 호출해 실행하는 프로그램 단위다. 동작 방식과 예시, 장단점, 함수와 트리거와의 차이, 최신 실무에서의 위치까지 정리한다.

최종 업데이트 2026.09.17

저장 프로시저(Stored Procedure)는 자주 사용하는 SQL 문들을 하나의 이름 아래 묶어 데이터베이스 서버에 미리 저장해 두고, 필요할 때 호출해서 실행하는 프로그램 단위다. 변수 선언, 조건문, 반복문 같은 절차적 로직을 담을 수 있으며, 네트워크 왕복을 줄이고 로직을 데이터 가까이에서 실행한다는 장점과 유지보수, 확장성 측면의 단점을 함께 가진다.

개념과 동작 방식

일반적인 애플리케이션은 SQL 문을 매번 데이터베이스로 전송하고, 데이터베이스는 그때마다 구문을 분석하고 실행 계획을 세운다. 저장 프로시저는 이 SQL 묶음을 데이터베이스 안에 객체로 저장해 두는 방식이다. 최초 생성 시 구문 검사가 이루어지고, 호출 시점에는 컴파일된 형태나 캐시된 실행 계획을 재사용할 수 있어 반복 호출에 유리하다.

호출하는 쪽에서는 CALL 프로시저명(인자) 형태로 이름과 매개변수만 전달하면 되므로, 여러 SQL 문이 필요한 작업도 네트워크 왕복 한 번으로 끝난다. 입력 매개변수(IN), 출력 매개변수(OUT), 양방향 매개변수(INOUT)를 통해 값을 주고받으며, 내부에서 트랜잭션 제어와 예외 처리도 할 수 있다.

작성 예시

MySQL에서 주문을 생성하면서 재고를 차감하는 프로시저 예시다.

DELIMITER //

CREATE PROCEDURE create_order (
    IN  p_user_id    BIGINT,
    IN  p_product_id BIGINT,
    IN  p_qty        INT,
    OUT p_order_id   BIGINT
)
BEGIN
    DECLARE v_stock INT;

    START TRANSACTION;

    SELECT stock INTO v_stock
    FROM product
    WHERE id = p_product_id
    FOR UPDATE;

    IF v_stock < p_qty THEN
        ROLLBACK;
        SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = '재고가 부족합니다';
    ELSE
        UPDATE product SET stock = stock - p_qty
        WHERE id = p_product_id;

        INSERT INTO orders (user_id, product_id, qty)
        VALUES (p_user_id, p_product_id, p_qty);

        SET p_order_id = LAST_INSERT_ID();
        COMMIT;
    END IF;
END //

DELIMITER ;

-- 호출
CALL create_order(42, 7, 3, @order_id);
SELECT @order_id;

장점과 단점

구분내용
장점여러 SQL을 한 번의 호출로 실행해 네트워크 왕복이 줄어든다. 실행 계획 재사용으로 반복 실행 성능이 좋다. 테이블 접근 권한 대신 프로시저 실행 권한만 부여해 보안을 강화할 수 있다. 매개변수 바인딩을 쓰면 SQL 인젝션(SQL Injection) 방어에도 도움이 된다. 여러 애플리케이션이 같은 로직을 공유할 수 있다.
단점비즈니스 로직이 애플리케이션과 데이터베이스 양쪽에 흩어져 유지보수가 어려워진다. 버전 관리, 테스트, 디버깅 도구가 애플리케이션 코드에 비해 빈약하다. 데이터베이스 제품마다 문법이 달라 이식성이 낮다. 로직이 데이터베이스에서 실행되므로 수평 확장이 어려운 데이터베이스에 CPU 부하가 집중된다.

함수, 트리거와의 비교

저장 프로시저와 자주 비교되는 것이 사용자 정의 함수(User-Defined Function)와 트리거(Trigger)다. 함수는 반드시 값을 반환하고 SELECT 문 안에서 호출될 수 있지만, 데이터를 변경하는 작업에는 제약이 많다. 프로시저는 반환값이 필수가 아니고 CALL로 독립 실행되며, 데이터 변경과 트랜잭션 제어가 자유롭다. 트리거는 직접 호출하는 것이 아니라 INSERT, UPDATE, DELETE 같은 이벤트가 발생할 때 데이터베이스가 자동으로 실행하는 로직이라는 점에서 둘과 구별된다.

항목프로시저함수트리거
실행 방법CALL로 명시적 호출쿼리 내에서 호출이벤트 발생 시 자동 실행
반환값선택(OUT 매개변수)필수없음
트랜잭션 제어가능제한적호출한 문장의 트랜잭션에 종속

실무에서의 위치

과거에는 성능과 보안을 이유로 핵심 로직을 프로시저에 담는 설계가 흔했고, 금융권 등 일부 도메인에서는 지금도 널리 쓰인다. 반면 최신 웹 서비스 개발에서는 비즈니스 로직을 애플리케이션 계층에 두고 데이터베이스는 저장에 집중시키는 구조가 주류가 되었다. 애플리케이션 서버는 쉽게 수평 확장이 되지만 데이터베이스는 그렇지 않고, 코드 리뷰와 테스트, 배포 파이프라인을 일원화하기에도 애플리케이션 쪽이 유리하기 때문이다. 따라서 대량 데이터 배치 처리나 데이터 마이그레이션처럼 데이터 근처에서 실행하는 것이 명백히 유리한 작업에 선별적으로 사용하는 것이 현재의 일반적인 권장 방향이다.

면접에서 이렇게 물어본다

  • 저장 프로시저의 장점과 단점을 설명하고, 어떤 상황에서 쓰는 것이 적절한가.
  • 저장 프로시저와 사용자 정의 함수의 차이는 무엇인가.
  • 저장 프로시저가 SQL 인젝션 방어와 보안에 도움이 되는 이유는 무엇인가.
  • 비즈니스 로직을 애플리케이션과 데이터베이스 중 어디에 두는 것이 좋다고 생각하는가, 그 근거는 무엇인가.
  • 저장 프로시저를 많이 쓰는 시스템에서 확장성 문제가 생기는 이유를 설명해 보라.
데이터베이스 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기