이번 강의에서는 PL/pgSQL에서 지원하는 데이터 타입이 뭐가 있는지 살펴보고, 그걸 어떻게 잘 쓰는지 배워볼 거야. 특히 네 가지 데이터 타입에 집중할 거야:
INTEGER- 숫자 다룰 때.TEXT- 문자열 처리할 때.BOOLEAN- 논리값 쓸 때.RECORD- 동적으로 구조가 바뀌는 데이터 다룰 때.
각 타입마다 예시를 통해 실제로 어떻게 쓰는지 보여줄게.
PL/pgSQL에서 지원하는 데이터 타입
PL/pgSQL에서는 PostgreSQL에서 익숙한 모든 데이터 타입을 쓸 수 있어. 기본적인 숫자 타입(INTEGER, NUMERIC)부터 배열, JSONB 같은 복잡한 타입까지 다 지원하지. 주요한 것들만 한번 훑어보자.
기본 타입:
INTEGER,BIGINT,FLOAT,NUMERIC— 숫자 타입.TEXT,CHAR,VARCHAR— 문자열 타입.BOOLEAN— 논리 데이터 타입.
복합 타입:
RECORD— 동적 데이터셋 다룰 때.ROWTYPE— 테이블 행 타입 다룰 때.- 배열, JSON — 이건 나중에 강의에서 다룰 거야.
INTEGER 타입 다루기
INTEGER는 제일 많이 쓰는 데이터 타입 중 하나야. 정수 저장할 때 쓰지. PL/pgSQL에서 계산, 레코드 id 다루기, 조건 체크 등에 자주 써.
예시: 레코드 개수 세기
예를 들어 students 테이블이 있다고 치고, 학생이 몇 명 있는지 알고 싶을 때 이렇게 해.
DO $$
DECLARE
total_students INTEGER; -- 학생 수 저장할 변수
BEGIN
SELECT COUNT(*) INTO total_students FROM students; -- 쿼리 결과를 변수에 저장
RAISE NOTICE '학생 수: %', total_students; -- 메시지 출력
END;
$$;
INTEGER 쓸 때 중요한 점:
- PL/pgSQL에서 변수에 값을 넣을 때는
INTO키워드를 써야 해. INTEGER에 소수값을 넣으려고 하면 에러 나. 그런 경우엔NUMERIC이나FLOAT를 써야 해.
TEXT 타입 다루기
TEXT는 문자열 데이터 저장할 때 써. 이름, 설명, 기타 텍스트 다룰 때 유용하지.
예시: 학생 이름 출력하기
이 예시에서는 students 테이블에서 모든 학생 이름을 출력해볼 거야.
DO $$
DECLARE
student_name TEXT; -- 학생 이름 저장 변수
BEGIN
FOR student_name IN SELECT name FROM students LOOP
RAISE NOTICE '학생 이름: %', student_name; -- 각 이름 출력
END LOOP;
END;
$$;
TEXT 다룰 때 유용한 함수들:
UPPER()와LOWER()— 대소문자 변환.CONCAT()— 문자열 합치기.LENGTH()— 문자열 길이 구하기.
예를 들면:
DO $$
DECLARE
full_name TEXT;
BEGIN
full_name := CONCAT('알렉스', ' 민'); -- 문자열 합치기
RAISE NOTICE '전체 이름: %', UPPER(full_name); -- 이름을 대문자로 출력
END;
$$;
BOOLEAN 타입 다루기
BOOLEAN은 논리값(TRUE, FALSE, NULL) 저장할 때 써. 조건 체크나 데이터 필터링할 때 특히 유용해.
예시: 학생 활성화 여부 체크
예를 들어 students 테이블에 is_active 컬럼이 있어서 학생이 활성화됐는지 표시한다고 해보자.
DO $$
DECLARE
is_active BOOLEAN; -- 활성화 여부 저장 변수
BEGIN
SELECT is_active INTO is_active FROM students WHERE id = 1; -- 테이블에서 값 가져오기
IF is_active THEN
RAISE NOTICE '학생이 활성화됨!';
ELSE
RAISE NOTICE '학생이 활성화되지 않음.';
END IF;
END;
$$;
BOOLEAN 쓸 때 중요한 점:
- 논리값은
IF나WHILE조건문에서 바로 쓸 수 있어. NULL은 "정의되지 않음"으로 간주되니까, 조건 체크할 때 주의해야 해.
RECORD 타입 다루기
RECORD는 구조가 미리 정해지지 않은 데이터 행을 저장할 수 있는 강력한 타입이야. 여러 컬럼을 반환하는 SQL 쿼리 결과를 다룰 때 특히 좋아.
예시: 테이블 모든 레코드 순회
아래 예시에서는 students 테이블의 모든 레코드를 돌면서 각 학생의 이름과 ID를 출력해볼 거야.
DO $$
DECLARE
student RECORD; -- 동적 데이터 행 저장 변수
BEGIN
FOR student IN SELECT id, name FROM students LOOP
RAISE NOTICE 'ID: %, 이름: %', student.id, student.name; -- 레코드 컬럼 접근
END LOOP;
END;
$$;
RECORD 쓸 때 중요한 점:
RECORD타입 변수는 루프 안이나SELECT INTO쿼리에서만 값이 채워져.- 컬럼에 접근할 때는
record.column_name식으로 써야 해.
테이블 작업용 ROWTYPE 데이터 타입
테이블의 한 행 전체를 저장하고 싶고, 타입도 명확하게 하고 싶으면 ROWTYPE을 쓰면 돼. 이 타입은 테이블 행 구조를 자동으로 따라가.
예시: ROWTYPE 타입 사용
DO $$
DECLARE
student students%ROWTYPE; -- students 테이블 행 구조를 가진 변수
BEGIN
SELECT * INTO student FROM students WHERE id = 1; -- 행 데이터를 변수에 저장
RAISE NOTICE '학생 이름: %, 코스: %', student.name, student.course;
END;
$$;
RECORD와 ROWTYPE의 차이점
| 특징 | RECORD | ROWTYPE |
|---|---|---|
| 컬럼 구조 | 미리 정해지지 않음 | 테이블이나 쿼리에 따라 다름 |
| 사용법 | 어떤 결과에도 유연하게 사용 | 구조가 고정됨 |
실전 예시
활성화된 학생 수와 이름을 반환하는 함수를 만들어보자.
CREATE FUNCTION active_students_report() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY
SELECT id, name FROM students WHERE is_active = TRUE;
END;
$$ LANGUAGE plpgsql;
함수 호출 예시:
SELECT * FROM active_students_report();
데이터 타입 다룰 때 자주 하는 실수
가끔 데이터 다루다가 에러가 날 수 있어. 대표적인 실수 몇 가지를 볼게:
- 타입 에러:
INTEGER변수에 문자열을 넣으려고 할 때 (예:my_var := 'abc';). TRUE나FALSE가 필요한데NULL을 쓸 때.RECORD를 초기화하지 않고 쓸 때.
에러를 피하려면:
- 항상 변수 타입을 명확하게 지정해.
- 테이블 컬럼의 데이터 타입을 기록 전에 꼭 확인해.
RAISE NOTICE같은 디버깅 명령을 활용해.
이제 PL/pgSQL에서 INTEGER, TEXT, BOOLEAN, RECORD 타입을 어떻게 다루는지 알았으니까, 더 복잡하고 강력한 PostgreSQL 프로시저 프로그램도 만들 수 있을 거야.
GO TO FULL VERSION