[PL/SQL] 컬렉션(Collection) - 개념
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 |
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(1, 2, 3); 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