CodeGym /행동 /SQL SELF /함수 만들 때 자주 하는 실수들 파헤치기

함수 만들 때 자주 하는 실수들 파헤치기

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

오늘은 함수 만들 때 흔히 하는 실수들, 왜 그런지, 그리고 어떻게 고치는지 알아볼 거야. 결국 디버깅을 통해서 진짜 개발자가 되는 거니까! Let's debug it!

PL/pgSQL 처음 배울 때 함수 만드는 게 좀 어렵게 느껴질 수 있어. PostgreSQL에서 오래 코딩한 사람들도 종종 실수하거든. 하나씩 같이 살펴보자.

1. RETURNS 키워드 빼먹기

PL/pgSQL은 함수 정의할 때 엄청 엄격해. 제일 많이 하는 실수 중 하나가 함수가 뭘 리턴하는지 타입을 안 적는 거야. 예시 볼게:

-- 에러: RETURNS 키워드 없음
CREATE FUNCTION incorrect_function() AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

PostgreSQL은 이 함수가 뭘 리턴해야 하는지 모르게 돼. RETURNS는 꼭 써야 하는 문법이고, 리턴 타입을 명확히 적어야 해 (예: RETURNS INT, RETURNS TEXT, 또는 RETURNS VOID).

고치는 방법: RETURNS 키워드랑 타입을 꼭 써줘:

CREATE FUNCTION correct_function() RETURNS INT AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

2. RETURN 없이 결과 리턴하려고 하기

초보 개발자들이 자주 까먹는 게, PL/pgSQL에서 값을 리턴하려면 꼭 RETURN을 써야 해. 예시:

-- 에러: RETURN 없음
CREATE FUNCTION missing_return() RETURNS TEXT AS $$
BEGIN
    'Hello, World!'; -- 그냥 문자열만 있음, 리턴 안 됨
END;
$$ LANGUAGE plpgsql;

여기서 'Hello, World!'는 그냥 써놓은 거고, 리턴이 아니야. PostgreSQL은 이걸 결과로 인식 못 해서 에러가 나.

고치는 방법: RETURN을 명확하게 써줘:

CREATE FUNCTION fixed_return() RETURNS TEXT AS $$
BEGIN
    RETURN 'Hello, World!';
END;
$$ LANGUAGE plpgsql;

3. 선언 안 한 변수에 값 넣으려고 하기

PL/pgSQL에서는 변수를 쓰기 전에 DECLARE 블록에서 꼭 선언해야 해. 예시:

-- 에러: my_var 변수 선언 안 됨
CREATE FUNCTION missing_variable() RETURNS VOID AS $$
BEGIN
    my_var := 'Hello, World!';
END;
$$ LANGUAGE plpgsql;

PostgreSQL은 my_var라는 변수가 뭔지 몰라, 왜냐면 DECLARE에서 선언 안 했으니까.

고치는 방법: 항상 DECLARE에서 변수 선언해줘:

CREATE FUNCTION declared_variable() RETURNS VOID AS $$
DECLARE
    my_var TEXT;
BEGIN
    my_var := 'Hello, World!';
END;
$$ LANGUAGE plpgsql;

4. VOID 타입 잘못 쓰기

VOID 타입은 함수가 아무것도 리턴 안 한다는 뜻이야. 근데 가끔 VOID 함수에서 RETURN에 값을 넣으려고 해서 에러가 나:

-- 에러: VOID 함수에서 RETURN 값 사용
CREATE FUNCTION void_example() RETURNS VOID AS $$
BEGIN
    RETURN 1; -- 값 리턴하면 안 됨
END;
$$ LANGUAGE plpgsql;

VOID 함수는 값을 리턴하면 안 돼. RETURN은 써도 되지만, 값 없이 써야 해.

고치는 방법: RETURN을 빼거나, 그냥 값 없이 써:

CREATE FUNCTION correct_void() RETURNS VOID AS $$
BEGIN
    -- 그냥 동작만 실행
    RAISE NOTICE '이 함수는 아무것도 리턴 안 해';
    RETURN; -- 함수 끝내기
END;
$$ LANGUAGE plpgsql;

5. 디버깅할 때 RAISE 잘못 쓰기

PL/pgSQL에서 디버깅할 때 RAISE NOTICE를 많이 써. 근데 포맷이나 변수 잘못 쓰면 에러가 나.

예시:

-- 에러: 포맷 잘못됨
CREATE FUNCTION debug_example() RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'The value is %'; -- 변수 없음
END;
$$ LANGUAGE plpgsql;

RAISE는 % 뒤에 변수나 값을 기대해. 그냥 %만 쓰면 PostgreSQL이 명령을 처리 못 해.

고치는 방법: 변수나 값을 제대로 넣어줘:

CREATE FUNCTION fixed_debug() RETURNS VOID AS $$
DECLARE
    my_var TEXT := 'PostgreSQL';
BEGIN
    RAISE NOTICE 'The value is %', my_var; -- 변수 넣음
END;
$$ LANGUAGE plpgsql;

6. 변수랑 컬럼 이름 충돌

변수 이름이 컬럼 이름이랑 같으면 헷갈릴 수 있어. 예시:

-- 에러: 변수랑 컬럼 이름 충돌
CREATE FUNCTION name_conflict() RETURNS TEXT AS $$
DECLARE
    name TEXT;
BEGIN
    SELECT name INTO name FROM students LIMIT 1; -- 어떤 name이 쓰이는 거지?
    RETURN name;
END;
$$ LANGUAGE plpgsql;

PL/pgSQL은 변수랑 컬럼 이름이 같으면 변수를 우선으로 써.

고치는 방법: 테이블에 별칭을 쓰거나, 이름 겹치지 않게 해.

CREATE FUNCTION fixed_conflict() RETURNS TEXT AS $$
DECLARE
    student_name TEXT;
BEGIN
    SELECT s.name INTO student_name FROM students s LIMIT 1;
    RETURN student_name;
END;
$$ LANGUAGE plpgsql;

7. 반복문에서 쿼리 잘못 쓰기

반복문 안에서 SQL 쿼리 쓸 때 실수 많이 해. 예시:

-- 에러: 반복문 안에서 쿼리 잘못 씀
CREATE FUNCTION cycle_error() RETURNS VOID AS $$
BEGIN
    FOR rec IN SELECT * FROM students LOOP
        EXECUTE 'UPDATE students SET active = TRUE WHERE id = ' || rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

SQL injection... 위험해! 쿼리 문자열 합치기는 진짜 안 좋은 습관이야. 보안 문제 생길 수 있어.

고치는 방법: 파라미터를 써줘:

CREATE FUNCTION safe_cycle() RETURNS VOID AS $$
BEGIN
    FOR rec IN SELECT * FROM students LOOP
        EXECUTE 'UPDATE students SET active = TRUE WHERE id = $1' USING rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

8. 데이터 타입 실수

에러 예시:

-- 에러: 데이터 타입 안 맞음
CREATE FUNCTION type_error() RETURNS INT AS $$
DECLARE
    my_var TEXT := 'not_a_number';
BEGIN
    RETURN my_var; -- INT 대신 TEXT 리턴해서 에러
END;
$$ LANGUAGE plpgsql;

PostgreSQL은 INT를 기대하는데 TEXT가 들어오면 에러야. 데이터 타입은 엄격하게 맞춰야 해.

고치는 방법? 타입을 맞추거나, 명시적으로 변환해줘:

CREATE FUNCTION type_correct() RETURNS INT AS $$
DECLARE
    my_var TEXT := '42';
BEGIN
    RETURN my_var::INT; -- 문자열을 숫자로 변환
END;
$$ LANGUAGE plpgsql;

꿀팁 & 베스트 프랙티스

  • 복잡한 함수는 작게 쪼개서 만들어. 그래야 디버깅, 테스트가 쉬워져.
  • 함수 안에 주석 많이 달아서 복잡한 부분 설명해줘.
  • 실제 테이블에 쓰기 전에 작은 데이터로 꼭 테스트해.
  • RAISE NOTICE로 디버깅해서 함수 흐름을 파악해.
  • SQL injection 피하기: 쿼리엔 꼭 파라미터 써.
-- 디버깅용 RAISE 사용 예시
DO $$
DECLARE
    total_students INT;
BEGIN
    SELECT COUNT(*) INTO total_students FROM students;
    RAISE NOTICE '전체 학생 수: %', total_students; -- 디버깅 메시지
END;
$$;

이 팁들만 잘 지키면 PL/pgSQL에서 삽질할 일 없이 머리 아픈 실수들 싹 피할 수 있어!

2
과제
SQL SELF, 레벨 50, 레슨 4
잠금
RAISE NOTICE를 사용한 디버깅
RAISE NOTICE를 사용한 디버깅
1
설문조사/퀴즈
간단한 함수 만들기, 레벨 50, 레슨 4
사용 불가능
간단한 함수 만들기
간단한 함수 만들기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION