1. 컬렉션 (Collection)
PL/SQL에서 다양한 데이터 타입을 가지면서 여러 로우(Row)에 해당하는 데이터를 가질 수 있는 자료 구조이다. 다른 프로그래밍 언어에서 볼 수 있는 리스트나 맵과 비슷한 기능을 한다.
TYPE 키워드를 사용해서 사용할 컬렉션의 구조를 정의할 수 있다. 주의해야할 점은 실제로 사용할 컬렉션은 TYPE 키워드로 선언한 타입을 사용해서 변수를 다시 한 번 선언해주어야 한다.
또한 PL/SQL의 컬렉션의 인덱스는 다른 프로그래밍 언어의 배열과 다르게 1부터 시작한다.
DECLARE
TYPE 타입명 IS TABLE OF NUMBER INDEX BY INTEGER_BINARY; -- TYPE 선언
변수명 타입명; -- 해당 TYPE을 가지는 컬렉션 변수 선언
BEGIN
END;
1. 연관 배열 (Associative Array)
키(Key)와 값(Value)로 구성된 컬렉션 키를 index라고 부르기 때문에 Index-By 테이블이라고도 부른다. Java의 맵(Map)과 대응되는 컬렉션이다.
TYPE 이름 IS TABLE OF 데이터 타입 INDEX BY 인덱스 데이터 타입
* INDEX로 사용 가능한 타입
BINARY_INTEGER : 정수
PLS_INTEGER : 정수
VARCHAR2(n) : 가변 문자열 (n은 1 ~ 32,672 (Byte))
%TYPE : 대상 오브젝트의 데이터 유형이 위 셋 중 하나일 경우 %TYPE 속성도 사용할 수 있다.
DECLARE
TYPE T_NUM1_ARRAY IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
TYPE T_NUM2_ARRAY IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
TYPE T_STR_MAP IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
NUM1_ARRAY T_NUM1_ARRAY;
NUM2_ARRAY T_NUM2_ARRAY;
STR_MAP T_STR_MAP;
BEGIN
FOR i IN 1..10 LOOP
NUM1_ARRAY(i) := i;
NUM2_ARRAY(i) := i * 2;
END LOOP;
STR_MAP('APPLE') := 'RED';
STR_MAP('BANANA') := 'YELLOW';
STR_MAP('GRAPE') := 'PURPLE';
DBMS_OUTPUT.PUT_LINE('NUM1_ARRAY 출력');
FOR i IN 1..NUM1_ARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM1_ARRAY(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE('---------------');
DBMS_OUTPUT.PUT_LINE('NUM2_ARRAY 출력');
FOR i IN 1..NUM2_ARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM2_ARRAY(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE('---------------');
DBMS_OUTPUT.PUT_LINE('STR_ARRAY 출력');
DBMS_OUTPUT.PUT_LINE(STR_MAP('APPLE'));
DBMS_OUTPUT.PUT_LINE(STR_MAP('BANANA'));
DBMS_OUTPUT.PUT_LINE(STR_MAP('GRAPE'));
END;
2. 가변 길이 배열 (VARRAY; Variable-Size Array)
선언할 때 최대 크기(최대 요소 개수)를 지정하여 생성하는 컬렉션이다. 지정한 최대 크기 이하의 요소를 저장할 수 있으며 사용하기 전 값을 넣어주는 초기화 작업이 필요하다.
TYPE 이름 IS ARRAY(최대 크기) OF 요소 데이터 타입
* 초기화
VARRAY는 사용하기 전에 요소를 넣어주어야 한다. 형식은 '변수명 := 타입명(요소1, 요소2, ...)' 이다.
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER; -- TYPE 선언
NUM_VARRAY T_NUM_VARRAY; -- TYPE의 변수 선언
BEGIN
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3, 4, 5); -- VARRAY 초기화
END;
다음과 같이 초기화하지 않고 사용하는 것은 불가능하다.
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER;
NUM_VARRAY T_NUM_VARRAY;
BEGIN
FOR i IN 1..NUM_VARRAY.COUNT LOOP
NUM_VARRAY(i) := i;
END LOOP;
END;
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER;
TYPE T_STR_VARRAY IS VARRAY(5) OF VARCHAR2(100);
NUM_VARRAY T_NUM_VARRAY;
STR_VARRAY T_STR_VARRAY;
BEGIN
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3, 4, 5);
STR_VARRAY := T_STR_VARRAY('APPLE', 'BANANA', 'GRAPE', 'MELON', 'STRAWBERRY');
DBMS_OUTPUT.PUT_LINE('NUM_VARRAY 출력');
FOR i IN 1..NUM_VARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM_VARRAY(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE('---------------');
DBMS_OUTPUT.PUT_LINE('STR_VARRAY 출력');
FOR i IN 1..STR_VARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(STR_VARRAY(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE('---------------');
END;
* VARRAY의 크기
가변 길이 배열이라는 이름처럼, TYPE 선언에서 설정한 최대 크기만 넘지 않으면 그 이하의 요소 개수를 가져도 무관하다.
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER;
NUM_VARRAY T_NUM_VARRAY;
BEGIN
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3);
DBMS_OUTPUT.PUT_LINE('NUM_VARRAY 출력');
FOR i IN 1..NUM_VARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM_VARRAY(i));
END LOOP;
END;
하지만 그 최대 크기를 넘길 수는 없다.
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER;
NUM_VARRAY T_NUM_VARRAY;
BEGIN
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3, 4, 5, 6);
DBMS_OUTPUT.PUT_LINE('NUM_VARRAY 출력');
FOR i IN 1..NUM_VARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM_VARRAY(i));
END LOOP;
END;
초기화한 요소의 개수를 초과하는 인덱스로 VARRAY를 참조하는 것은 불가능하다.
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER;
NUM_VARRAY T_NUM_VARRAY;
BEGIN
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3);
DBMS_OUTPUT.PUT_LINE(NUM_VARRAY(4));
END;
초기화 이후에 다시 초기화 하는 것도 가능하다.
DECLARE
TYPE T_NUM_VARRAY IS VARRAY(5) OF NUMBER;
NUM_VARRAY T_NUM_VARRAY;
BEGIN
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3);
DBMS_OUTPUT.PUT_LINE('NUM_VARRAY 출력');
FOR i IN 1..NUM_VARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM_VARRAY(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE('---------------');
NUM_VARRAY := T_NUM_VARRAY(1, 2, 3, 4, 5);
DBMS_OUTPUT.PUT_LINE('NUM_VARRAY 다시 출력');
FOR i IN 1..NUM_VARRAY.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NUM_VARRAY(i));
END LOOP;
DBMS_OUTPUT.PUT_LINE('---------------');
END;
3. 중첩 테이블 (Nested Table)
연관 배열과 비슷한 모양이지만 인덱스가 모두 숫자로 되어있는 컬렉션이다. 연관 배열과 가변 길이 배열을 합친 형태이며 사용법은 가변 길이 배열과 비슷하다.
선언 방식은 기존 연관 배열에서 'INDEX BY' 구문만 제외하면 된다. 다만 가변 길이 배열과 마찬가지로 사용 전 초기화가 필요하다.
TYPE 이름 IS TABLE OF 데이터 타입
DECLARE
TYPE T_NESTEDT IS TABLE OF VARCHAR2(10);
NESTEDT T_NESTEDT;
BEGIN
NESTEDT := T_NESTEDT('APPLE', 'BANANA', 'GRAPE', 'PEAR', 'MELON');
DBMS_OUTPUT.PUT_LINE('NESTEDT 출력');
FOR i IN 1..NESTEDT.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(NESTEDT(i));
END LOOP;
END;
'데이터베이스 > Oracle' 카테고리의 다른 글
[PL/SQL] 레코드 (Record) (0) | 2023.07.13 |
---|---|
[PL/SQL] 컬렉션 (Collection) - 메소드 (0) | 2023.07.13 |
[PL/SQL] BULK COLLECT INTO (0) | 2023.07.11 |
[PL/SQL] 동적쿼리 (EXECUTE IMMEDIATE) (0) | 2023.07.11 |
[OracleDB] 두 개의 테이블에서 조인 조건으로 사용할 수 있는 컬럼을 가져오는 함수 (0) | 2023.06.15 |