PL/pgSQL 개요 — SQL에 절차적 힘을 더하는 언어
PL/pgSQL 개요 — SQL에 절차적 힘을 더하는 언어
SQL은 강력하고 배우기 쉽지만, 클라이언트와 서버 사이의 왕복(round-trip) 비용이 문제가 될 때가 있어요. 매 쿼리를 서버로 보내고 결과를 받고 계산한 뒤 또 쿼리를 보내는 반복은, 특히 클라이언트가 서버와 다른 머신에 있으면 네트워크 오버헤드까지 더해져요. PL/pgSQL은 이 일련의 계산과 쿼리를 데이터베이스 서버 내부에 묶어 넣어서, 절차적 언어의 힘과 SQL의 사용 편의성을 동시에 누리면서 통신 오버헤드를 크게 줄여줍니다.
출처: 공식문서
PL/pgSQL이란 무엇인가요
PL/pgSQL은 PostgreSQL용으로 적재 가능한(loadable) 절차적 언어예요. 이 언어의 설계 목표는 다음과 같은 절차적 언어를 만드는 것이었습니다:
- 함수, 프로시저, 트리거를 만들 수 있고,
- SQL 언어에 제어 구조를 더하며,
- 복잡한 계산을 수행하고,
- 사용자 정의 타입·함수·프로시저·연산자를 모두 상속하며,
- 서버가 신뢰하도록(trusted) 정의될 수 있고,
- 사용하기 쉽다.
PL/pgSQL로 만든 함수는 내장 함수를 쓸 수 있는 어디든 사용할 수 있어요. 예를 들어 복잡한 조건부 계산 함수를 만든 뒤, 나중에 연산자를 정의하는 데 쓰거나 인덱스 표현식에 사용할 수도 있어요.
PostgreSQL 9.0 이후로 PL/pgSQL은 기본 설치되는데, 여전히 적재 가능한 모듈이라 보안에 민감한 관리자가 굳이 제거할 수도 있습니다.
PL/pgSQL을 쓰면 좋은 점
SQL은 PostgreSQL을 포함한 대부분의 관계형 DB가 사용하는 쿼리 언어로, 이식성 있고 배우기 쉬워요. 하지만 모든 SQL 문장은 서버가 하나씩 개별적으로 실행해야 합니다. 즉 클라이언트 애플리케이션이 각 쿼리를 서버로 보내고 처리될 때까지 기다렸다가 결과를 받고, 계산을 한 뒤 또 쿼리를 보내야 하죠. 이 모든 과정이 프로세스 간 통신을 수반하고, 클라이언트가 서버와 다른 머신이면 네트워크 오버헤드까지 추가됩니다.
PL/pgSQL로 계산 블록과 쿼리 시리즈를 서버 내부에 묶으면:
- 클라이언트와 서버 사이의 추가 왕복이 사라지고,
- 클라이언트가 필요로 하지 않는 중간 결과를 마샬링·전송하지 않아도 되며,
- 여러 번의 쿼리 파싱을 피할 수 있어요.
저장 함수를 쓰지 않는 애플리케이션과 비교하면 상당한 성능 향상을 기대할 수 있어요. 게다가 SQL의 모든 데이터 타입·연산자·함수도 그대로 쓸 수 있습니다.
지원되는 인자·결과 데이터 타입
PL/pgSQL 함수는 서버가 지원하는 어떤 스칼라·배열 타입도 인자로 받고 반환할 수 있어요. 이름으로 지정된 어떤 **복합 타입(행 타입)**도 받거나 반환할 수 있고, record로 선언하면 입력은 아무 복합 타입이나, 반환은 호출 쿼리에서 정해지는 열을 가진 행 타입이 됩니다.
VARIADIC마커로 가변 인자 수를 받는 함수를 선언할 수 있어요(SQL 함수와 똑같이 동작).- **다형 타입(polymorphic)**을 받고 반환하도록 선언할 수도 있어서, 함수가 다루는 실제 타입이 호출마다 달라질 수 있어요.
- **집합(테이블)**을 반환하도록 선언할 수 있는데, 결과 집합의 각 원소에 대해
RETURN NEXT를 실행하거나, 쿼리 결과를 출력하는RETURN QUERY로 생성해요. - 유용한 반환 값이 없다면
void를 반환하도록 선언할 수도 있어요(그 대신 프로시저로 작성해도 됩니다). - 명시적 반환 타입 대신 출력 파라미터로 선언할 수도 있는데, 언어에 근본적으로 새로운 능력을 주는 건 아니지만 여러 값을 반환할 때 편리해요.
RETURNS SETOF대신RETURNS TABLE표기법도 사용할 수 있어요.
구체적인 예시는 PL/pgSQL 선언 파트와 제어 구조의 "값 반환하기" 섹션에서 다룹니다.
더 알아보기 (Learn more)
- PL/pgSQL 제어 구조 (Control Structures) — 조건·반복·반환 흐름
- PL/pgSQL 문장 (Statements) — SQL 실행과 결과 다루기
- PL/pgSQL 전체 문서 — 선언·표현식·트리거 등