더북(TheBook)

사용자 정의 데이터 타입

2장에서 SQL 데이터 타입을 설명할 때 오라클에서는 사용자 정의 데이터 타입도 지원한다고 했었는데, 이제 사용자 정의 데이터 타입을 다룰 때가 된 것 같다. 컬렉션 절에서 왜 사용자 정의 타입을 설명하는지 의아할 텐데, 이 절에서 다루는 이유는 사용자 정의 타입이 컬렉션과 밀접한 관계가 있기 때문이다.

지금까지 배웠던 컬렉션 타입과 예제에서는 ‘TYPE~’으로 시작하는 구문으로 PL/SQL 블록의 선언부에서 컬렉션을 선언했었는데, 이런 식으로 사용하면 컬렉션은 해당 PL/SQL 블록의 실행이 완료되면 사라져 버린다. 따라서 이전 PL/SQL 블록에서 선언했던 동일한 컬렉션 타입을 다른 블록에서 재사용하려면 또 다시 선언해서 변수에 할당해 사용해야 한다. 하지만 자주 사용하는 컬렉션 타입은 이렇게 매번 선언하기가 매우 번거롭다. VARCHAR2, NUMBER와 같은 빌트인 SQL 타입처럼 특정 컬렉션 타입도 미리 정의해서 사용할 수 있다면 매우 편리할 것이다. 이렇게 자주 사용하는 컬렉션 타입을 미리 정의해 놓고 사용할 수 있는 방법이 있는데, 바로 사용자 정의 타입이 그 주인공이다(PL/SQL 블록, 사용자 정의 타입 외에도 패키지에서도 컬렉션을 선언할 수 있는데, 이 내용은 12장: 패키지에서 다룰 것이다).

사용자 정의 타입으로 사용할 수 있는 컬렉션 타입은 연관 배열을 제외한 VARRAY와 중첩 테이블 뿐이다. 반면 컬렉션은 아니지만 OBJECT(객체) 타입도 사용자 정의 타입으로 사용할 수 있다(앞에서 컬렉션이 객체지향 프로그래밍에서 등장하는 클래스와 비슷한 개념이라고 했는데 사실 완벽하게 같지는 않다. 일반적인 클래스는 다양한 데이터 타입을 멤버 변수로 가질 수 있고 멤버 함수도 정의해 사용 가능하지만, 컬렉션은 한 가지 타입으로만 요소가 구성되며 멤버 메소드도 직접 정의하는 것이 아니라 오라클에서 제공하는 빌트인 메소드를 사용한다. 이에 반해 OBJECT(객체) 타입은 클래스와 거의 흡사하고 심지어 상속도 할 수 있다).

각 컬렉션 타입별, 사용자 정의 타입의 선언 구문은 다음과 같다.

    • VARRAY : CREATE OR REPLACE TYPE 타입명 IS VARRAY(최대 크기) OF 값타입 ;
    • 중첩 테이블 : CREATE OR REPLACE TYPE 타입명 IS TABLE OF 값타입 ;
    • OBJECT : CREATE OR REPLACE TYPE 타입명 IS OBJECT (
               멤버1 멤버1_데이터타입,
               멤버2 멤버2_데이터타입,
               ...
               );

VARRAY나 중첩 테이블 모두 기존의 TYPE 대신 CREATE OR REPLACE TYPE을 사용하는 점만 제외하면 나머지는 배웠던 내용과 같고, OBJECT 타입의 각 항목은 컬렉션과는 달리 레코드처럼 여러 종류의 데이터 타입을 사용할 수 있다(OBJECT 타입은 멤버 함수도 정의할 수 있다.) 그럼 두 가지 컬렉션 타입을 사용자 정의 데이터 타입으로 만들어 보자.

입력

    -- 5개의 문자형 값으로 이루어진 VARRAY 사용자 정의 타입 선언
    CREATE OR REPLACE TYPE ch11_va_type IS VARRAY(5) OF VARCHAR2(20);

    -- 문자형 값의 중첩테이블 사용자 정의 타입 선언
    CREATE OR REPLACE TYPE ch11_nt_type IS TABLE OF VARCHAR2(20);

결과

    TYPE CH11_VA_TYPE이(가) 컴파일되었습니다.
    TYPE CH11_NT_TYPE이(가) 컴파일되었습니다.

입력

    -- 사용자 정의 타입인 va_type과 nt_type 사용
    DECLARE
      vva_test ch11_va_type;  -- VARRAY인 va_type 변수 선언
      vnt_test ch11_nt_type;  -- 중첩 테이블인 nt_type 변수 선언

    BEGIN
      -- 생성자를 사용해 값 할당(총 5개지만 최초 3개만 값 할당)
      vva_test := ch11_va_type('FIRST', 'SECOND', 'THIRD', '', '');
      vnt_test := ch11_nt_type('FIRST', 'SECOND', 'THIRD', '');

      DBMS_OUTPUT.PUT_LINE('VARRAY의 1번째 요소값: ' || vva_test(1));
      DBMS_OUTPUT.PUT_LINE('중첩테이블의 1번째 요소값: ' || vnt_test(1));

    END;

결과

    VARRAY의 1번째 요소값: FIRST
    중첩 테이블의 1번째 요소값: FIRST

별도의 컬렉션 타입을 생성, 즉 오라클 객체로 만들어 놓으니 사용할 때마다 매번 선언할 필요 없이 변수만 선언해서 바로 사용할 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.