ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PL/SQL] 컬렉션(Collection) - 개념
    IT, 프로그래밍/Database (Oracle) 2019. 1. 23. 09:12




    Collection = 다양한 데이터 타입을 가질 수 있는 동시에, 여러 로우에 해당하는 데이터를 가질 수 있는 자료형.


    특징


    생성자를 이용해 초기화 가능

    빌트인 함수와 프로시저로 구성된 컬렉션 메소드 제공




    1) 연관 배열(Associative Array)


    키와 값으로 구성된 컬렉션. 키를 Index라고 부르기 때문에 Index-by 테이블 이라고도 함.

    자바에 있는 Map 구조에 대응되는 컬렉션이다.




    TYPE 이름 IS TABLE OF 값타입 INDEX BY 인덱스타입;


    으로 정의하여 사용한다.


    인덱스타입 = 키 타입임.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    DECLARE
     
        TYPE av_type IS TABLE OF VARCHAR2(40)
                        INDEX BY PLS_INTEGER;
        vav_test av_type;
     
    BEGIN
     
        vav_test(10) := '이것은 10에 대한 값임';
        vav_test(20) := '이것은 20에 대한 값임';
     
        DBMS_OUTPUT.PUT_LINE(VAV_TEST(10));
        DBMS_OUTPUT.PUT_LINE(VAV_TEST(20));
     
    END;
    cs


    PL/SQL 프로시저가 성공적으로 완료되었습니다.

    이것은 10에 대한 값임
    이것은 20에 대한 값임


    인덱스 타입을 정수형으로 하고, 값은 문자타입으로 설정하였다.

    설정한 대로 데이터가 잘 들어가는 것을 확인할 수 있다.

    만약 인덱스에 숫자가 아닌 타입을 넣으면 어떻게 될까?

    1
    2
    3
    4
    5
    6
     
    BEGIN
        vav_test('숫자 10') := '이것은 10에 대한 값임';
        vav_test(20) := '이것은 20에 대한 값임';
    .....
     
    cs



    END;

    오류 보고 -

    ORA-06502: PL/SQL: numeric or value error: character to number conversion error

    ORA-06512: at line 9


    컴파일 에러를 발생시키며 적절한 키 값이 아니라고 나온다.




    2. 가변 길이 배열 (VARRY, Variable-Size Array)





    선언할 때 크기(요소 개수)를 지정한 만큼 배열을 만든다. 일반적인 프로그래밍 언어에서 지원하는 배열(Array)에 해당함.

    중요한 것은 요소 크기가 크더라도, 원소를 요소 크기 이하로 초기화하면 그 만큼만 초기화된다.




    Type 이름 IS VARRY(최대 크기) OF 배열 요소의 타입



    생성자가 사용해 초기화하기 전 까지 각 요소에 값을 할당하거나 읽어올 수 없음. 

    생성자는 배열명(값1, 값2, 값3.... ) 형태로 사용. 

    NULL값으로 초기화 하면 해당 요소는 참조가 가능.

    기본으로 NULL값으로 참조되지 않는다. 만약 5개의 배열에 3개만 초기화 시켰다면 나머지 인덱스에는 접근이 불가능하다.


    * 시작 인덱스는 1부터 시작한다. 0이 아니다. 1부터 시작한다. 이 점을 꼭 유의할 것 !!



     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    DECLARE
     
        TYPE va_type IS VARRAY(5) OF VARCHAR2(20);
        vva_test va_type;
     
    BEGIN
        vva_test := va_type('FIRST''SECOND''THIRD''''');
        FOR i IN 1..5
        LOOP
        DBMS_OUTPUT.PUT_LINE(vva_test(i));
        END LOOP;
      
    END;
     
    cs


    FIRST

    SECOND

    THIRD





    초기화 시킨 대로 값이 나오는 것을 확인할 수 있다.


    그럼 여기서 3번째 자리에 값을 넣어보자.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    DECLARE
     
        TYPE va_type IS VARRAY(5) OF VARCHAR2(20);
        vva_test va_type;
     
    BEGIN
        vva_test := va_type('FIRST''SECOND''THIRD''''');
       
        FOR i IN 1..5
        LOOP
        DBMS_OUTPUT.PUT_LINE(vva_test(i));
        END LOOP;
        
        vva_test(3) := '네번째';
       
        FOR j IN 1..5
        LOOP
        DBMS_OUTPUT.PUT_LINE(vva_test(j));
        END LOOP;
        
      
    END;
     
    cs




    FIRST

    SECOND

    THIRD


    FIRST

    SECOND

    네번째





    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    DECLARE
     
        TYPE va_type IS VARRAY(5) OF VARCHAR2(20);
        vva_test va_type;
     
    BEGIN
        vva_test := va_type('FIRST''SECOND''THIRD');
       
        FOR i IN 1..3
        LOOP
        DBMS_OUTPUT.PUT_LINE(vva_test(i));
        END LOOP;
        DBMS_OUTPUT.PUT_LINE(vva_test(4));
     
    END;
    cs



    3번째 인덱스까지 초기화 하였으나 4번째 인덱스에 접근하였다.



    END;

    오류 보고 -

    ORA-06533: Subscript beyond count

    ORA-06512: at line 13

    06533. 00000 -  "Subscript beyond count"

    *Cause:    An in-limit subscript was greater than the count of a varray



    초기화 되지 않는 인덱스이므로 당연히 에러가 발생한다.


    가변 배열의 경우, 초기화 되는 경우 5개 크기의 배열을 선언하였지만, 3개를 초기화 하였으면 3개의 크기만큼만 배열이 잡히는 것을 유의하자.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    DECLARE
     
        TYPE va_type IS VARRAY(5) OF INTEGER;
        vva_test va_type;
     
    BEGIN
        vva_test := va_type(123);
       
    END;
    cs




    실제 초기화 된 가변 배열의 모습이다.







    3. 중첩 테이블 (Nested Table)





    연관 배열과 비슷한 모양이나, 인덱스가 모두 숫자로 되어있다.

    연관배열과 가변배열을 합친 모습의 컬렉션이며 가변 배열과 비슷하게 제어할 수 있다.

    예를 들어, for문을 통해 순회할 수 있으며 초기화도 비슷하게 이루어진다.


    TYPE 이름 IS TABLE OF 값 데이터 타입;


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    DECLARE
    TYPE nt_typ IS TABLE OF VARCHAR2(10);
        vnt_test nt_typ;
    BEGIN
        vnt_test := nt_typ('FIRST''SECOND''THIRD');
     
        FOR i IN 1..3
    LOOP
        DBMS_OUTPUT.PUT_LINE(vnt_test(i));
    END LOOP;
    END;
    cs


    FIRST

    SECOND

    THIRD




Designed by Tistory.