바닥코딩

PL/SQL 컬렉션 본문

데이터 베이스/오라클 PLSQL

PL/SQL 컬렉션

개발공부개발공부 2021. 3. 24. 13:47

 컬랙션은 내부 구성 항목이 모두 동일한 데이터 타입을 가진 유형의 자료 구조입니다 일반적인 프로그래밍 언어를 학습해 보신분들은 알고 있는 개념일테지만 대표적으로 배열과 같은 구조 등이 컬렉션에 해당합니다. 컬렉션의 각 항복은 변수명(인덱스) 와 같은 표현식을 사용하여 접근이 가능합니다

컬렉션 타입의 종류

 오라클 PL/SQL에서 지원하는 컬렉션 타입에는  Associative Array(연관 배열), VARRAY(가변 크기 배열), Nested Table (중첩 테이블) 등이 이에 해당합니다

비교항목         /        컬렉션타입 Associative Array VARRAY Nested Table
컬렉션 항목의 개수 미지정  지정  미지정
인덱스 유형 문자열 또는 정수  정수  정수
초기화되지 않은 상태 Empty null null
ADT(객체타입) 불가능  가능  가능

 

Associative Array

 Associative Array는 컬렉션 항복의 개수를 사전에 지정하지 않습니다. 인덱스는 정수 또는 문자열을 인덱스로 사용할 수 있는데, 심지어 음수도 사용이 가능합니다 유일하게 초기화를 필요로 하지 않고, 변수는 null을 할당 할 수 없습니다. 정리하지면, Associative Array는 키-값 의 쌍으로 이루어진 무한 배열이라고 볼 수 있습니다.   

 예제를 통해 알아보겠습니다.

declare
    -- 정수를 인덱스로 하는 Associative Array 타입 선언
    type city is table of varchar2(64) index by pls_integer ;
    -- 문자열을 인덱스로 하는 Associative Array 타입 선언
    type population is table of  number  index by varchar2(64);
    v_city city;
    v_Population population;
begin
    v_city (-1) := '서울';
    v_city (0) := '부산';
    v_city (2) := '대전';

    v_Population('서울') := 10373234 ;
    v_Population('부산') := 3812392 ;
    v_Population('대전') := 1390510 ;

    DBMS_OUTPUT.PUT_LINE('도시별 인구');
    DBMS_OUTPUT.PUT_LINE('===========================================');
    DBMS_OUTPUT.PUT_LINE(v_city(-1) || ':' ||
                         to_char(v_Population(v_city(-1)),'999,999,999'));
    DBMS_OUTPUT.PUT_LINE(v_city(-1) || ':' ||
                     to_char(v_Population(v_city(0)),'999,999,999'));
    DBMS_OUTPUT.PUT_LINE(v_city(-1) || ':' ||
                     to_char(v_Population(v_city(2)),'999,999,999'));
end;

 위 예제와 같이 Associative Array는 [TYPE 타입명 IS TABLE OF 데이터타입 INDEX BY 인덱스테이터 타입] 형식으로 사용 됩니다. 추가적으로, BULK COLLECT 함수를 사용하면 여러건의 SELECT 결과를 Associative Array 에 담을 수 있습니다.

declare
     type string_array is table of varchar2(100) index by pls_integer ;
     v_arr string_array;
begin
    select ename
        bulk collect  into v_arr
    from emp;
    DBMS_OUTPUT.PUT_LINE('Associative Arrat 컬랙션 개수 :' || v_arr.COUNT);
end;

 

VARRAY(Variable-Size Array)

 VARRAY는 우리가 일반적으로 생각하는 그 배열입니다. 일반적으로 다른 프로그래밍 언어에서 선언 하는 것과 비슷하게 VARRAY 는 배얄이 가질 수 있는 사이즈를 지정해야합니다.  또한 반드시 초기화를 해줘야 오류를 미연에 방지하는 것이 가능합니다.

 VARRAY는 아래아 같이 선언하고 사용합니다

  [TYPE 타입명 IS VARRAY(크기) OF 데이터타입] 

다음 예제를 통해 확인해 보겠습니다.

declare
     type languages is varray(10) of varchar(64); -- varry 선언
     v_lang languages;
     v_lang2 languages := languages('한국어', '중국어', '영어');
begin
    v_lang := languages();
    v_lang := languages('한국어');
    v_lang := languages('한국어', '중국어');

    v_lang.extend(2);  -- 배열 확장 메소드 
    v_lang(3) := '일본어';
    v_lang(4) :=  '영어';

    DBMS_OUTPUT.PUT_LINE('언어 목록' );
    dbms_output.PUT_LINE('=============');
    for i in v_lang.First .. v_lang.LAST
    loop
        DBMS_OUTPUT.PUT_LINE(to_char(i)|| ':' || v_lang(i));
    end loop;
end;

VARRAY도 Associative Array 와 마찬가지로 BULK COLLECT가 사용 가능 합니다.

--varray bulk collect (select 결과를 varray로 대입)
declare
    type string_array is varray(20) of varchar2(100);
    v_arr string_array;
begin
    select ename bulk collect  into v_arr --v_arr 변수에 쿼리 결과 삽입
    from emp
    where rownum <= 20;
    DBMS_OUTPUT.PUT_LINE('varry count :' || v_arr.COUNT);
end;

Nested Table

Nested Table은 순서가 고정되어 있지 않고, 크기도 고정되지 않은 데이터의 집합을 저장하는데 가장 적합한 컬렉션입니다.  컬렉션의 인덱스는 1에서 시작하여 순차적으로 진행합니다 하지만 값을 저장하거나 조회할떄 항목의 순서가 항상 동일함을 보장하지 않습니다.  이 말이 잘 이해가 되지 않을거같아 자세히 서술하자며

  •  배열은 크기가 사전에 선언 되지만 Nested Table의 크기는 동적으로 증가한다
  • 동적으로 증가하기 떄문에 항상 밀집해 있지 않으며 예를 들어 일부를 삭제하면 현재 데이터 사이 사이 공간이 비어 빈 항목이 존재할 수 있다

등으로 해석할 수 있겠습니다.

Nested Table의 구조는 다음과 같습니다 [TYPE 타입명 IS TABLE OF 데이터타입] 해당  구조는 예제를 통해 더 자세히 알아보겠습니다.

DECLARE
    TYPE city IS TABLE OF VARCHAR2(64);   -- Nested Table 선언
    v_city city;
    v_city2 city :=  city('서울','대전','부산');
BEGIN
    v_city := city('서울','대전','부산','광주','인천');
    
    v_city :=city(); -- 초기화
    
    v_city.extend; v_city(1) := '서울'; --Nested Table 값 추가
    v_city.extend; v_city(1) := '대전';
    v_city.extend; v_city(1) := '부산';
    v_city.extend; v_city(1) := '대구';
    DBMS_OUTPUT.PUT_LINE('도시개수 :'||v_city.COUNT||'개' );
    
    for i in v_city.FIRST .. v_city.LAST
    loop
        if v_city.EXISTS(i) then
            DBMS_OUTPUT.PUT_LINE(v_city(i));
        end if;
     end loop;
    
    v_city.delete(3);   -- 3번째 항목을 삭제 
   BMS_OUTPUT.PUT_LINE('도시개수 :'||v_city.COUNT||'개' );
    
    for i in v_city.first .. v_city.LAST
    loop
        if v_city.EXISTS(i) then
            DBMS_OUTPUT.PUT_LINE(v_city(i));
        end if;
    end loop;  -- 삭제된 3번쨰 항목은 출력이 되지 않는다 
  
END;

 여기서 데이터를 삭제한 항목은 참조할 수 없으며 항상 순서가 일반적이지 않을 수도 있다는 사실은 유념해야 합니다. 하나더, Nested Table에서도 BULK COLLECT 를 사용할 수 있습니다.

DECLARE 
     TYPE string_arr IS TABLE OF VARCHAR2(100);
     v_arr string_arr;
BEGIN
    SELECT ename
        BULK COLLECT INTO v_arr
        FROM EMP;
     DBMS_OUTPUT.PUT_LINE('Nested table 컬렉션 건수 :' || v_arr.COUNT);       
END;

 

 

 

'데이터 베이스 > 오라클 PLSQL' 카테고리의 다른 글

저장 서브프로그램  (0) 2021.03.29
트리거  (0) 2021.03.24
cursor  (0) 2021.03.24
순환문  (0) 2021.02.25
분기문  (0) 2021.02.25