기록

PostgreSQL Function & Procedure 배운 것 정리

als982001 2025. 4. 13. 14:45

 

1, 개요

 PostgreSQL은 강력한 사용자 정의 기능(UDF)을 제공하며, 함수(function)와 프로시저(procedure)를 통해 재사용 가능한 로직을 정의하고 활용할 수 있다. 그리고 이번에는 이것을 배웠고, 배운 것을 간단히 정리하려 한다.

 

2, 함수 (Function)

  • 반환값이 있는 SQL 코드 블록
  • SELECT문 안에서도 호출 가능
  • 입력값에 따라 계산 또는 조건 처리 후 값을 리턴
  • PostgreSQL은 함수의 이름 + 인자(입력값, 출력값) 타입까지 합쳐서 구별하기 때문에 같은 함수 이름을 오버로딩할 수 있다.
  • 함수의 성능 관련 속성
    • VOLATILE: 기본값으로, 같은 인자여도 결과가 바뀔 수 있을 있다는 것을 나타낸다.
    • STABLE: 트랜젝션 내에서 인자가 같은면 결과가 같다 (조회만 가능)
    • IMMUTABLE: 항상 동일 인자에 대해 동일한 결과

2-1. 기본 함수 문법

CREATE OR REPLACE FUNCTION function_name(param TYPE)
RETURNS return_type AS
$$
  SQL or PLPGSQL block
$$
LANGUAGE SQL | PLPGSQL;

 

2-2. 함수 오버로딩 예시

-- 인자 없음
CREATE OR REPLACE FUNCTION hello_world()
RETURNS TEXT AS 
$$
	SELECT 'hello_world';
$$
LANGUAGE SQL;

-- 하나의 인자
CREATE OR REPLACE FUNCTION hello_world(user_name TEXT)
RETURNS TEXT AS 
$$
	SELECT 'hello ' || user_name;
$$
LANGUAGE SQL;

-- 두 개의 텍스트 인자 (이름 미지정 → 위치로 참조)
CREATE OR REPLACE FUNCTION hello_world(TEXT, TEXT)
RETURNS TEXT AS 
$$
	SELECT 'hello ' || $1 || ' and ' || $2;
$$
LANGUAGE SQL;

 

2-3. 사용자 정의 타입을 받아서 조건 분기

CREATE OR REPLACE FUNCTION is_hit_or_flop(movie movies)
RETURNS TEXT AS
$$
	SELECT CASE
		WHEN movie.revenue > movie.budget THEN 'Hit'
		WHEN movie.revenue < movie.budget THEN 'Flop'
		ELSE 'N/A'
 	END
$$
LANGUAGE SQL;

 

2-4. 함수에서 TABLE 반환

CREATE FUNCTION is_hit_or_flop(movie movies)
RETURNS TABLE (hit_or_flop TEXT, other_thing NUMERIC) AS
$$
	SELECT CASE
		WHEN movie.revenue > movie.budget THEN 'Hit'
		WHEN movie.revenue < movie.budget THEN 'Flop'
		ELSE 'N/A'
	END, 11111;
$$ LANGUAGE SQL IMMUTABLE;

 

2-5. Trigger 함수

  • 트리거에 의해 실행되는 특수한 함수
  • INSERT, UPDATE, DELETE 같은 이벤트 전후에 작동해서 값을 자동 갱신할 수 있다.
CREATE FUNCTION set_updated_at()
RETURNS TRIGGER AS
$$
	BEGIN
		NEW.updated_at = CURRENT_TIMESTAMP;
		RETURN NEW;
	END;
$$ LANGUAGE PLPGSQL;

CREATE TRIGGER updated_at
BEFORE UPDATE ON movies
FOR EACH ROW EXECUTE FUNCTION set_updated_at();

 

3. 프로시저 (Procedure)

  • 반환값이 없는 혹은 없어도 되는 SQL 코드 블록
  • CALL 문으로 직접 실행
  • 복잡한 로직 실행, 트랜잭션 단위 작업 처리 등에 유용

 

3-1. 기본 문법

CREATE PROCEDURE procedure_name(...)
AS $$
BEGIN
  -- 여러 SQL 문
END;
$$ LANGUAGE PLPGSQL;

 

3-2. revenue를 0에서 NULL로 설정

CREATE PROCEDURE set_zero_revenue() AS
$$
  UPDATE movies SET revenue = NULL WHERE revenue = 0;
$$ LANGUAGE SQL;

CALL set_zero_revenue();

 

3-3. IN/OUT 파라미터 사용

CREATE PROCEDURE hello_world_p(IN name TEXT, OUT greeting TEXT) AS
$$
BEGIN
  greeting = 'Hello ' || name;
END;
$$ LANGUAGE PLPGSQL;

CALL hello_world_p('nico', NULL);

 

4. Function/Procedure 비교 요약 정리

항목 Function Procedure
반환값 있음 없음, 또는 없어도 됨
호출 방식 SELECT 또는 FROM 구문에서 사용 CALL로 실행
목적 계산, 값 변환 상태 변경, 로직 실행
사용 위치 쿼리 안에서 호출 가능 단독 실행 (CALL)
SELECT hello_world(); CALL set_zero_revenue();
  • 함수는 무언가를 반환
  • 프로시저는 무언가를 실행
  • 둘 다 재사용 가능하고, 복잡한 SQL 로직을 깔끔하게 정리할 수 있다.

 


관련 문서