CodeGym /행동 /SQL SELF /PL/pgSQL에서 함수로부터 값 반환하는 방법

PL/pgSQL에서 함수로부터 값 반환하는 방법

SQL SELF
레벨 50 , 레슨 1
사용 가능

PostgreSQL에서 함수를 짤 때 제일 먼저 고민하는 것 중 하나가 결과를 어떻게 반환하지?야. 어떤 때는 그냥 숫자 하나만 반환하면 되고, 어떤 때는 테이블 전체를 반환해야 할 때도 있어. 심지어 여러 데이터셋을 반환해야 할 때도 있지. 여기서는 제일 기본적인 RETURN부터 RETURN QUERY, RETURNS TABLE, SETOF까지 다뤄볼게.

하나의 결과: RETURN

함수가 딱 하나의 값만 반환해야 한다면 — 예를 들어 합계나 행 개수 — 그냥 RETURN 쓰면 돼.

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT;
BEGIN
    SELECT COUNT(*) INTO total FROM students;
    RETURN total;
END;
$$ LANGUAGE plpgsql;

PL/pgSQL에서 함수를 만들 때는 반환 타입을 꼭 지정해야 해. 이건 RETURNS 키워드로 정하는데, 함수가 어떤 "형식"의 결과를 반환하는지 알려주는 거야. 숫자 하나, 텍스트, 데이터 테이블 등 뭘 반환하든 RETURNS 줄에 꼭 써줘야 해.

간단한 예시:

CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
    RETURN a + b;
END;
$$ LANGUAGE plpgsql;

여기서 RETURNS INT는 함수가 숫자를 반환한다는 뜻이야.

하나의 값 반환하기

제일 기본적인 것부터 시작해보자 — 값을 하나만 반환하는 함수. 예를 들어 students 테이블에서 학생 수를 세는 함수:

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT;
BEGIN
    SELECT COUNT(*) INTO total FROM students; -- 쿼리 결과를 total 변수에 저장
    RETURN total; -- 결과 반환
END;
$$ LANGUAGE plpgsql;

이제 이 함수를 호출해볼 수 있어:

SELECT count_students(); -- 학생 수를 반환함

RETURNS TABLE로 여러 값 반환하기

가끔은 값 하나가 아니라 여러 레코드를 반환해야 할 때가 있어. 예를 들어 모든 학생의 이름과 id 리스트를 반환하고 싶을 때. 이럴 때 RETURNS TABLE을 써.

CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY SELECT id, name FROM students; -- 쿼리 결과를 테이블로 반환
END;
$$ LANGUAGE plpgsql;

이제 이 함수를 호출해보면:

SELECT * FROM get_students(); -- 모든 학생이 담긴 테이블을 반환함

RETURNS TABLE 키워드에 주목! 이건 함수가 지정된 컬럼(idname)을 가진 테이블을 반환한다는 뜻이야.

RETURN QUERY 사용하기

위 예제가 마음에 들었을 거야. 근데 한 가지 더: RETURN QUERY는 PL/pgSQL에서 쿼리 결과를 바로 반환할 수 있게 해주는 마법 같은 키워드야. 이걸로 전체 쿼리 결과든, 일부든 바로 반환할 수 있어.

예를 들어, 데이터베이스에서 active = TRUE로 표시된, 현재 수강 중인 학생만 반환하고 싶다고 해보자:

CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT id, name
    FROM students
    WHERE active = TRUE; -- 활성 학생만 반환
END;
$$ LANGUAGE plpgsql;

이제 함수 호출해서 활성 학생 데이터만 받을 수 있어:

SELECT * FROM get_active_students();

RETURNS TABLE 없이 여러 행 반환하기

어떤 경우에는 RETURNS TABLE 없이도 여러 행을 반환하고 싶을 수 있어. 이럴 때 SETOF 타입을 쓰면 돼. 같은 구조의 행들을 반환할 수 있지. 예시:

CREATE FUNCTION get_student_names() RETURNS SETOF TEXT AS $$
BEGIN
    RETURN QUERY
    SELECT name
    FROM students;
END;
$$ LANGUAGE plpgsql;

이 함수는 학생 이름만 리스트로 반환해:

SELECT * FROM get_student_names();

입력값에 따라 값 반환하기

함수가 항상 고정된 결과만 반환하는 건 아니야. 파라미터를 받아서 동적으로 결과를 바꿀 수도 있지.

예를 들어, 학생 id로 데이터를 반환하는 함수:

CREATE FUNCTION get_student_by_id(student_id INT) RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT id, name
    FROM students
    WHERE id = student_id; -- student_id 파라미터 사용
END;
$$ LANGUAGE plpgsql;

이제 특정 학생 정보를 이렇게 조회할 수 있어:

SELECT * FROM get_student_by_id(3); -- ID = 3인 학생 데이터 반환

복잡한 데이터 반환 (여러 데이터셋)

가끔 데이터가 너무 복잡해서 여러 데이터셋을 반환해야 할 때가 있어. 이럴 때는 커서를 쓸 수 있어. 예를 들어, 함수에서 활성 학생 리스트와 비활성 학생 리스트 두 개를 반환하고 싶을 때:

CREATE FUNCTION get_students_status() RETURNS SETOF RECORD AS $$
BEGIN
    RETURN QUERY
    SELECT id, name, 'active' AS status
    FROM students
    WHERE active = TRUE;

    RETURN QUERY
    SELECT id, name, 'inactive' AS status
    FROM students
    WHERE active = FALSE;
END;
$$ LANGUAGE plpgsql;

이제 두 데이터셋을 한 번에 받을 수 있어:

SELECT * FROM get_students_status();

RETURNS 쓸 때 자주 하는 실수

반환 타입을 안 썼을 때: 함수가 뭘 반환하는지 안 쓰면 PostgreSQL이 에러를 내. 예시:

CREATE FUNCTION no_return_type() AS $$ -- 에러, RETURNS 안 씀
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

데이터 타입이 안 맞을 때: 반환하는 값이 선언한 타입이랑 맞는지 꼭 확인해. INT를 반환한다고 해놓고 문자열을 반환하면 안 돼.

RETURN QUERY를 빼먹었을 때: 복잡한 쿼리를 실행할 때 RETURN QUERY를 안 쓰면 함수가 아무것도 반환 안 해.

여러 값 반환할 때 잘못 쓴 경우: 행 데이터를 반환하는데 SETOFTABLE을 안 쓰면 PostgreSQL이 에러를 내.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION