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 키워드에 주목! 이건 함수가 지정된 컬럼(id와 name)을 가진 테이블을 반환한다는 뜻이야.
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를 안 쓰면 함수가 아무것도 반환 안 해.
여러 값 반환할 때 잘못 쓴 경우: 행 데이터를 반환하는데 SETOF나 TABLE을 안 쓰면 PostgreSQL이 에러를 내.
GO TO FULL VERSION