CodeGym /행동 /SQL SELF /함수와 프로시저의 차이점

함수와 프로시저의 차이점

SQL SELF
레벨 51 , 레슨 4
사용 가능

많은 프로그래밍 언어에서는 함수와 프로시저가 거의 차이가 없어. 근데 SQL에서는 다르지. PostgreSQL에서 함수와 프로시저는 단순히 코드를 실행하는 두 가지 방법이 아니야. 이건 완전히 다른 사고방식이야.

SQL에서 함수는 DB의 데이터를 바꿀 수 없어. 전달받은 데이터만 가지고 결과를 반환해야 해. 주로 SELECT 쿼리 안에서 쓰려고 만든 거야.

SQL에서 프로시저는 DB를 바꾸려고 만들어진 거야. 그래서 트랜잭션을 다룰 수 있고(함수랑 다르게), DB에 뭔가를 쓸 수도 있어. 그리고 SELECT 쿼리 안에서는 쓸 수 없어.

간단하게 비교해보면 이래:

특징 함수 (FUNCTION) 프로시저 (PROCEDURE)
데이터 반환 ✅ 응 (RETURNS ...) ❌ 아니 (동작만 함)
호출 방법 SELECT, PERFORM CALL
쿼리에서 사용 가능 ✅ 응 ❌ 아니
DO에서 사용 가능 ✅ 응 ❌ 아니
COMMIT, ROLLBACK 지원 ❌ 아니 ✅ 응
PostgreSQL에 도입된 시점 처음부터 11버전부터

SQL에서의 차이

일반 SQL에서 함수는 표현식이랑 비슷해: 계산해서 값을 반환하지. 프로시저는 명령문이야: 뭔가를 실행하지만 표현식에는 못 써.

SQL에서 함수

SELECT calculate_discount(200);
  • WHERE, ORDER BY, INSERT, UPDATE 등에서 쓸 수 있어.
  • 순수해야 해: DB 상태를 바꾸면 안 됨(IMMUTABLE/STABLE이면).

SQL에서 프로시저

CALL process_order(123);
  • 결과를 반환하지 않아.
  • COMMIT, ROLLBACK, RAISE 호출, 루프 실행 가능.

PL/pgSQL에서의 차이

PostgreSQL의 함수는 계산 묶음이라고 생각하면 돼. 엄청 유연해서 파라미터 전달, 조건문, 루프, 커서, 서브쿼리, 행/스칼라/테이블 반환 다 가능해.

PL/pgSQL 함수

CREATE FUNCTION square(x INT) RETURNS INT AS $$
BEGIN
    RETURN x * x;
END;
$$ LANGUAGE plpgsql;

특징:

  • RETURNS 필수
  • DECLARE, BEGIN, END, LOOP, IF, CASE 사용 가능
  • COMMIT/ROLLBACK 불가
  • SELECT, UPDATE, CHECK, WHERE, RETURNING에서 호출 가능

호출 예시:

SELECT square(5);  -- 25 반환

PL/pgSQL 프로시저

프로시저는 동작 제어 메커니즘이야. 이런 상황에 딱이야:

  • 여러 단계의 로직 실행할 때;
  • 대량 데이터 업데이트/삽입할 때;
  • 트랜잭션 제어 필요할 때: COMMIT, ROLLBACK, SAVEPOINT.
CREATE PROCEDURE log_event(msg TEXT) AS $$
BEGIN
    INSERT INTO logs(message) VALUES (msg);
    COMMIT;
END;
$$ LANGUAGE plpgsql;

특징:

  • RETURNS 없음
  • CALL로만 호출
  • COMMIT, ROLLBACK, SAVEPOINT 사용 가능
  • 배치 처리, 마이그레이션, ETL에 적합

호출 예시:

CALL log_event('처리 완료');

함수와 프로시저가 나뉜 이유

왜냐면 SQL에서 목적이 다르거든:

함수 프로시저
"뭔가 계산해서 반환" "뭔가 실행하고 결과는 반환 안 함"
SQL에서 호출 명령어처럼 호출
트랜잭션 제어 불가 트랜잭션 제어 가능
SELECT, JOIN, WHERE에서 사용 CALL, 스크립트에서 사용

프로시저의 핵심 장점 — COMMIT

프로시저는 자기 안에서 트랜잭션을 제어할 수 있어. 즉, 프로시저 안에서 바로 이렇게 할 수 있음:

BEGIN;
-- 로직
SAVEPOINT point1;
-- 업데이트 시도
ROLLBACK TO point1;
COMMIT;

그리고 함수에서는 COMMIT이랑 ROLLBACK이 금지야. 만약 시도하면: ERROR: invalid transaction termination in function 이런 에러 나옴

즉, 함수는 반드시 결정적이고 안전해야 하고, 프로시저는 "더러운 일"도 할 수 있어 — 정리, 로그, 삽입 등.

비교 표

특징 FUNCTION PROCEDURE
값 반환 RETURNS
SELECT에서 사용
호출 방법 SELECT, PERFORM, DO 오직 CALL
트리거에서 사용 가능 ❌ (함수만 가능)
내부 트랜잭션 (COMMIT) ❌ 금지 ✅ 허용
OUT 파라미터 사용 RETURNS TABLE, RECORD OUT 파라미터 직접 사용
계산에 적합 🚫 적합하지 않음
ETL, 로딩에 적합 🚫 제한적 ✅ 완전 적합
커서 사용 가능 ✅ 응 ✅ 응

언제 뭘 써야 할까?

함수를 써야 할 때:

  • 반환값이 필요할 때;
  • SELECT에서 호출하거나, 데이터 필터링할 때;
  • 간단한 계산, 체크, SQL 래퍼일 때.

프로시저를 써야 할 때:

  • 복잡한 동작을 해야 할 때;
  • 트랜잭션 제어가 필요할 때;
  • 배치 처리, 데이터 이동, 아카이브, 로깅 등 할 때.
1
설문조사/퀴즈
제어 구조, 레벨 51, 레슨 4
사용 불가능
제어 구조
제어 구조
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION