기본 콘텐츠로 건너뛰기

PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용

PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용

AI 생성 이미지: PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용
AI 생성 이미지: PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용

PL/pgSQL로 함수를 만들다 보면 테이블 이름이나 조건을 런타임에 결정해야 할 때가 자주 있습니다. 이런 상황에서 동적으로 작성한 SQL을 실행해 결과를 함수 반환값으로 바로 돌려주는 문법이 RETURN QUERY EXECUTE입니다.

이 글은 RETURN QUERY EXECUTE의 개념과 기본 문법, 사용 예제, 안전한 파라미터 바인딩 방법, 그리고 실무에서 주의해야 할 점까지 핵심만 골라 정리합니다.

1. RETURN QUERY EXECUTE란 무엇인가?

RETURN QUERY EXECUTE는 함수 내부에서 문자열로 조립한 SQL 문을 실행하고, 그 실행 결과를 현재 함수의 결과 집합(Result Set)에 추가하는 구문입니다. 보통 RETURNS TABLE이나 SETOF 형태의 함수에서 주로 사용합니다.

기본 형식


RETURN QUERY EXECUTE '
  -- 여기에 동적 SQL 작성
  SELECT ...
';
      

위 구조는 함수가 미리 정의한 컬럼 구조에 맞춰 행을 쌓아 반환합니다. 정적 쿼리를 쓸 때의 RETURN QUERY와 달리 실행할 SQL을 런타임에 조합할 수 있다는 점이 핵심입니다.

2. 가장 기본적인 예제: 테이블 이름을 파라미터로 받기

다음 예제는 함수 인자로 전달된 table_name을 이용해 해당 테이블의 idname 컬럼을 조회하고, 그 결과를 그대로 반환하는 간단한 패턴을 보여줍니다.


CREATE OR REPLACE FUNCTION get_data(table_name TEXT)
RETURNS TABLE (id INT, name TEXT)
AS $$
BEGIN
  RETURN QUERY EXECUTE '
    SELECT id, name
    FROM ' || table_name || '
  ';
END;
$$ LANGUAGE plpgsql;
    

호출은 일반 SELECT처럼 합니다.


SELECT * FROM get_data('my_table');
    

내부적으로는 전달된 테이블 이름을 결합해 실제 쿼리를 만들고 이를 실행합니다. 아래와 같은 SQL이 실행되는 셈입니다.


SELECT id, name
FROM my_table;
    
주의: 문자열 결합만으로 테이블 이름을 붙이면 SQL 인젝션 위험이 발생할 수 있습니다. 외부 입력을 그대로 사용해야 할 때는 반드시 quote_ident(), format() 등을 통해 식별자와 값을 안전하게 처리하세요.

3. 파라미터와 함께 쓰기: USING 절로 안전하게 바인딩

테이블 이름뿐 아니라 WHERE 절에 변수를 넣어 필터링해야 한다면, USING을 활용해 값 바인딩을 하는 것이 안전합니다. 이렇게 하면 파라미터가 적절히 이스케이프되고 타입 검사도 PostgreSQL이 담당합니다.

예제: 특정 ID 이상만 조회하는 함수


CREATE OR REPLACE FUNCTION get_data_min_id(table_name TEXT, min_id INT)
RETURNS TABLE (id INT, name TEXT)
AS $$
BEGIN
  RETURN QUERY EXECUTE
    'SELECT id, name
       FROM ' || quote_ident(table_name) || '
      WHERE id >= $1'
  USING min_id;
END;
$$ LANGUAGE plpgsql;
    

호출 예시는 다음과 같습니다.


SELECT * FROM get_data_min_id('my_table', 100);
    

이 예제에서 $1USING min_id로 전달된 값과 바인딩되어, 직접 문자열에 삽입하는 방식보다 안전합니다.

4. RETURN QUERY vs RETURN QUERY EXECUTE vs 단순 RETURN

비슷해 보여 헷갈리기 쉬운 세 가지 키워드를 간단히 구분해 보겠습니다.

  • RETURN 함수에서 단일 값이나 레코드를 반환할 때 사용합니다. 반환 타입에 따라 동작이 달라집니다.
  • RETURN QUERY 정적 SQL을 실행해 나온 결과를 함수의 결과셋에 추가할 때 씁니다.
  • RETURN QUERY EXECUTE 런타임에 조합한 SQL 문자열을 실행하고 그 결과를 결과셋에 추가할 때 사용합니다.

예를 들어 고정된 쿼리를 반환할 때는 아래처럼 RETURN QUERY를 쓰면 됩니다.


RETURN QUERY
  SELECT id, name
    FROM fixed_table
   WHERE use_yn = 'Y';
    

반대로 테이블 이름이나 조건을 동적으로 조합해야 한다면 RETURN QUERY EXECUTE가 적합합니다.

5. RETURN QUERY EXECUTE 사용 시 주의사항 & 팁

5-1. SQL 인젝션 주의

단순 문자열 결합(... || table_name || ...)은 외부 입력을 그대로 포함하면 매우 위험합니다. 다음 같은 방법을 사용해 위험을 줄이세요.

  • quote_ident(table_name) 등 식별자용 quote 함수 사용
  • USING 절을 통해 값 바인딩 적용
  • format()%I, %L 포맷을 조합해 안전하게 조립

5-2. RETURNS TABLE과 궁합이 좋다

RETURNS TABLE(...) 형태는 반환할 컬럼 구조를 미리 선언해 두고, 내부에서 RETURN QUERYRETURN QUERY EXECUTE로 결과를 채우는 패턴이 깔끔합니다. 타입 안전성과 가독성 측면에서 장점이 큽니다.

5-3. 복잡한 리포트/집계 함수에 유용

조회 대상 테이블이나 WHERE/ORDER BY가 조건에 따라 바뀌는 리포트 함수나 동적 집계 쿼리를 만들 때 RETURN QUERY EXECUTE는 매우 유용합니다. 다만, 가독성과 테스트 가능성을 고려해 코드 구조를 잘 설계하세요.

6. 마무리 – 언제 RETURN QUERY EXECUTE를 써야 할까?

  • 함수 내에서 런타임에 SQL을 조립해 실행해야 할 때
  • 그 결과를 테이블 형태(결과셋)로 반환하려 할 때
  • 테이블 이름, 컬럼 또는 WHERE 조건 등이 상황에 따라 바뀌는 경우

위와 같은 상황이라면 RETURN QUERY EXECUTE가 적절한 선택입니다. 다만 보안과 유지보수를 위해 문자열 결합에만 의존하지 말고 USING, quote 함수, format() 등을 적극 활용해 안전하고 읽기 쉬운 코드를 작성하세요.

실무에서 복잡한 PL/pgSQL 함수를 만들 때 본문에서 소개한 방법들을 참고하면, 동적 쿼리를 안정적으로 관리할 수 있습니다.

🚀 이 주제, 우리 서비스에 어떻게 적용할까요?

PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용를 실제 서비스와 조직에 녹여보고 싶다면, 현재 아키텍처와 운영 방식을 한 번 점검해 보는 것부터 시작해 보세요. 팀 위키나 기술 블로그, 사내 스터디 주제로도 아주 좋습니다.

이 글이 도움이 됐다면, 비슷한 엔터프라이즈 사례 글들도 함께 살펴보면서 우리 조직에 맞는 운영 상용구를 정의해 보세요.

AI 생성 이미지: PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용
AI 생성 이미지: PL/pgSQL RETURN QUERY EXECUTE 완전 정리 – RETURNS TABLE과 동적 쿼리 활용

댓글

이 블로그의 인기 게시물

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 (Request Parameter 전체보기)

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 Java Servlet Request Parameter 완전 정복 웹 애플리케이션에서 클라이언트로부터 전달되는 Request Parameter 를 확인하는 것은 필수입니다. 이 글에서는 Java Servlet 과 JSP 에서 GET/POST 요청 파라미터를 전체 출력하고 디버깅하는 방법을 다양한 예제와 함께 소개합니다. 1. 기본 예제: getParameterNames() 사용 Enumeration<String> params = request.getParameterNames(); System.out.println("----------------------------"); while (params.hasMoreElements()){ String name = params.nextElement(); System.out.println(name + " : " + request.getParameter(name)); } System.out.println("----------------------------"); 위 코드는 요청에 포함된 모든 파라미터 이름과 값을 출력하는 기본 방법입니다. 2. HTML Form과 연동 예제 <form action="CheckParamsServlet" method="post"> 이름: <input type="text" name="username"><br> 이메일: <input type="email" name="email"><b...

PostgreSQL 달력(일별,월별)

SQL 팁: GENERATE_SERIES로 일별, 월별 날짜 목록 만들기 SQL 팁: GENERATE_SERIES 로 일별, 월별 날짜 목록 만들기 데이터베이스에서 통계 리포트를 작성하거나 비어있는 날짜 데이터를 채워야 할 때, 특정 기간의 날짜 목록이 필요할 수 있습니다. PostgreSQL과 같은 데이터베이스에서는 GENERATE_SERIES 함수를 사용하여 이 작업을 매우 간단하게 처리할 수 있습니다. 1. 🗓️ 일별 날짜 목록 생성하기 2020년 1월 1일부터 12월 31일까지의 모든 날짜를 '1 day' 간격으로 생성하는 쿼리입니다. WITH date_series AS ( SELECT DATE(GENERATE_SERIES( TO_DATE('2020-01-01', 'YYYY-MM-DD'), TO_DATE('2020-12-31', 'YYYY-MM-DD'), '1 day' )) AS DATE ) SELECT DATE FROM date_series 이 쿼리는 WITH 절(CTE)을 사용하여 date_series 라는 임시 테이블을 만들고, GENERATE_SERIES 함수로 날짜를 채웁니다. 결과 (일별 출력) 2. 📅 월별 날짜 목록 생성하기 동일한 원리로, 간격을 '1 MONTH' 로 변경하면 월별 목록을 생성할 수 있습니다. TO...

CSS로 레이어 팝업 화면 가운데 정렬하는 방법 (top·left·transform 완전 정리)

레이어 팝업 센터 정렬, 이 코드만 알면 끝 (CSS 예제 포함) 이벤트 배너나 공지사항을 띄울 때 레이어 팝업(center 정렬) 을 깔끔하게 잡는 게 생각보다 어렵습니다. 화면 크기가 변해도 가운데에 고정되고, 모바일에서도 자연스럽게 보이게 하려면 position , top , left , transform 을 정확하게 이해해야 합니다. 이 글에서는 아래 내용을 예제로 정리합니다. 레이어 팝업(center 정렬)의 기본 개념 자주 사용하는 position: absolute / fixed 정렬 방식 질문에서 주신 스타일 top: 3.25%; left: 50%; transform: translateX(-50%) 의 의미 실무에서 바로 쓰는 반응형 레이어 팝업 HTML/CSS 예제 1. 레이어 팝업(center 정렬)이란? 레이어 팝업(레이어 팝업창) 은 새 창을 띄우는 것이 아니라, 현재 페이지 위에 div 레이어를 띄워서 공지사항, 광고, 이벤트 등을 보여주는 방식을 말합니다. 검색엔진(SEO) 입장에서도 같은 페이지 안에 HTML이 존재 하기 때문에 팝업 안의 텍스트도 정상적으로 인덱싱될 수 있습니다. 즉, “레이어 팝업 센터 정렬”, “레이어 팝업 만드는 방법”과 같이 관련 키워드를 적절히 넣어주면 검색 노출에 도움이 됩니다. 2. 질문에서 주신 레이어 팝업 스타일 분석 질문에서 주신 스타일은 다음과 같습니다. <div class="layer-popup" style="width:1210px; z-index:9001; position:absolute; top:3.25%; left:50%; transform:translateX(-50%);"> 레이어 팝업 내용 <...