> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tibero-manuals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tibero.com/tibero-manuals/7.2.6.manuals/tbpsm-guide/composite-types/collection-methods.md).

# 컬렉션 함수와 프러시저

컬렉션 타입에 사용할 수 있는 함수와 프러시저를 설명합니다.

tbPSM은 컬렉션 타입을 쉽고 편하게 사용하기 위해 컬렉션 함수와 프러시저를 제공합니다. 모두 컬렉션 변수의 메소드 형태로 호출합니다.

<table><thead><tr><th width="153">구분</th><th width="169">이름</th><th>설명</th></tr></thead><tbody><tr><td>컬렉션 함수</td><td><p>EXISTS</p><p>COUNT</p><p>LIMIT</p><p>FIRST, LAST</p><p>PRIOR, NEXT</p></td><td>컬렉션 함수는 항상 반환값을 가짐</td></tr><tr><td>프러시저</td><td><p>EXTEND</p><p>TRIM</p><p>DELETE</p></td><td>프러시저는 반환값을 갖지 않음</td></tr></tbody></table>

초기화되지 않은 컬렉션 변수에 이들을 사용하는 경우 **COLLECTION\_IS\_NULL** 예외 상황이 발생합니다. 예외는 EXISTS 함수로, 초기화되지 않은 컬렉션 변수에도 예외 상황 없이 FALSE를 반환합니다.

## **컬렉션 타입별 사용 범위**

컬렉션 함수와 프러시저 중 일부는 특정 컬렉션 타입에만 사용합니다. 타입별 사용 범위는 다음과 같습니다.

<table><thead><tr><th width="180">이름</th><th width="150">네스티드 테이블</th><th width="150">인덱스 테이블</th><th>배열</th></tr></thead><tbody><tr><td>EXISTS, COUNT</td><td>지원</td><td>지원</td><td>지원</td></tr><tr><td>LIMIT</td><td>지원. NULL 반환</td><td>지원. NULL 반환</td><td>지원. 선언한 크기 반환</td></tr><tr><td>FIRST, LAST</td><td>지원</td><td>지원</td><td>지원</td></tr><tr><td>PRIOR, NEXT</td><td>지원</td><td>지원</td><td>지원</td></tr><tr><td>EXTEND</td><td>지원</td><td>미지원</td><td>지원</td></tr><tr><td>TRIM</td><td>지원</td><td>미지원</td><td>지원</td></tr><tr><td>DELETE</td><td>지원</td><td>지원</td><td>인자 없는 DELETE만 지원</td></tr></tbody></table>

미지원으로 표시된 조합을 사용하면 컴파일 단계에서 TBR-15081이 발생합니다. 인덱스 테이블은 초기화 없이 키에 값을 대입해 크기가 늘어나므로 EXTEND와 TRIM을 사용하지 않고, 배열은 구성요소가 항상 연속적이므로 크기를 줄일 때 TRIM을 사용합니다. 배열에서 인자 없는 DELETE는 모든 구성요소를 지우며(COUNT가 0이 되고 변수는 NULL이 되지 않음), 인덱스를 지정하는 DELETE(n)과 DELETE(m, n)에서 TBR-15081이 발생합니다.

## **EXISTS 함수**

EXISTS 함수는 n번째 구성요소의 존재 여부를 TRUE, FALSE로 반환합니다. 이 값은 DELETE 프러시저에 의해 달라질 수 있습니다.

다음은 EXISTS 함수의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
BEGIN
    IF my_sunday.EXISTS(2) THEN
        DBMS_OUTPUT.PUT_LINE('Second sunday is ' || my_sunday(2));
    END IF;
    my_sunday.DELETE(2);
    IF my_sunday.EXISTS(2) = false THEN
        DBMS_OUTPUT.PUT('Second sunday is disappeared. ');
        DBMS_OUTPUT.PUT_LINE(' because of work');
    END IF;
    IF my_sunday.EXISTS(10) = false THEN
        DBMS_OUTPUT.PUT_LINE('Only 4 or 5 weeks in a month');
    END IF;
END;
/
```

다음은 실행 결과입니다.

```
Second sunday is 9
Second sunday is disappeared.  because of work
Only 4 or 5 weeks in a month
```

## **COUNT 함수**

COUNT 함수는 컬렉션 변수의 구성요소 개수를 반환합니다. 이 값은 DELETE 프러시저에 의해 달라질 수 있습니다.

다음은 COUNT 함수의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
BEGIN
    DBMS_OUTPUT.PUT_LINE(my_sunday.COUNT);
    my_sunday.DELETE(2);
    DBMS_OUTPUT.PUT_LINE(my_sunday.COUNT);
END;
/
```

다음은 실행 결과입니다.

```
5
4
```

## **LIMIT 함수**

LIMIT 함수는 컬렉션 타입에 따라 반환되는 값이 다릅니다.

<table><thead><tr><th width="206">컬렉션 타입</th><th>설명</th></tr></thead><tbody><tr><td>네스티드 테이블, 인덱스 테이블</td><td>구성요소의 길이 제한이 없으므로 NULL을 반환</td></tr><tr><td>배열</td><td>배열을 선언할 때 지정된 값이 반환됨</td></tr></tbody></table>

다음은 LIMIT 함수의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    TYPE monday_arr IS VARRAY(7) OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
    my_monday monday_arr := monday_arr(3, 10, 17, 24, 31);
BEGIN
    DBMS_OUTPUT.PUT_LINE('Limit of table = ' || my_sunday.LIMIT);
    DBMS_OUTPUT.PUT_LINE('Limit of varray = ' || my_monday.LIMIT);
END;
/
```

다음은 실행 결과입니다. 네스티드 테이블의 LIMIT은 NULL이므로 아무것도 출력되지 않습니다.

```
Limit of table =
Limit of varray = 7
```

## **FIRST, LAST 함수**

FIRST 함수는 첫 번째 구성요소의 인덱스를 반환하고, LAST 함수는 마지막 구성요소의 인덱스를 반환합니다. 이 값은 DELETE 프러시저에 의해 달라질 수 있습니다. 구성요소가 하나도 없으면 두 함수는 NULL을 반환합니다.

FIRST, LAST 함수는 컬렉션 타입에 따라 반환되는 값이 다릅니다.

<table><thead><tr><th width="182">컬렉션 타입</th><th>설명</th></tr></thead><tbody><tr><td>네스티드 테이블</td><td><ul><li>FIRST 함수 : 남아 있는 가장 작은 인덱스를 반환</li><li>LAST 함수 : 남아 있는 가장 큰 인덱스를 반환</li></ul></td></tr><tr><td>인덱스 테이블</td><td><ul><li>FIRST 함수 : 가장 낮은 키값을 반환</li><li>LAST 함수 : 가장 높은 키값을 반환</li></ul></td></tr><tr><td>배열</td><td><ul><li>FIRST 함수 : 항상 1을 반환</li><li>LAST 함수 : 항상 COUNT 함수와 같은 값을 반환</li></ul></td></tr></tbody></table>

다음은 FIRST, LAST 함수의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
BEGIN
    DBMS_OUTPUT.PUT_LINE('First sunday is ' || my_sunday.FIRST());
    DBMS_OUTPUT.PUT_LINE('Last sunday is ' || my_sunday.LAST());
    my_sunday.DELETE(1);
    DBMS_OUTPUT.PUT_LINE('First sunday is ' || my_sunday.FIRST());
    my_sunday.DELETE(5);
    DBMS_OUTPUT.PUT_LINE('Last sunday is ' || my_sunday.LAST());
END;
/
```

다음은 실행 결과입니다.

```
First sunday is 1
Last sunday is 5
First sunday is 2
Last sunday is 4
```

## **PRIOR, NEXT 함수**

PRIOR 함수는 n번째 구성요소의 바로 앞에 구성요소 인덱스를 반환하고, NEXT 함수는 n번째 구성요소의 바로 다음의 구성요소 인덱스를 반환합니다. 컬렉션 타입 중 인덱스 테이블은 키값의 순서에 따라 PRIOR, NEXT 함수의 값을 반환합니다. 이때 키값의 순서는 기본적으로 키값의 바이너리 값을 비교할 때 정해집니다. 숫자 키 인덱스 테이블에서는 두 함수가 모두 인접 키를 반환하고, 문자열 키 인덱스 테이블에서는 NEXT가 인접 키를 반환합니다. 문자열 키에서 역방향으로 순회할 때는 키 목록을 따로 모아 사용합니다.

n의 값은 EXTEND, TRIM, DELETE 프러시저에 의해 달라질 수 있습니다. n의 값에 따라 각 함수는 반환하는 값이 다음과 같이 다릅니다.

<table><thead><tr><th>함수</th><th width="179">n의 값</th><th>반환값</th></tr></thead><tbody><tr><td>PRIOR</td><td>n &#x3C; 1</td><td>NULL</td></tr><tr><td></td><td>FIRST와 같을 경우</td><td>NULL</td></tr><tr><td></td><td>LAST보다 클 경우</td><td>항상 LAST 함수의 값을 반환</td></tr><tr><td>NEXT</td><td>n &#x3C; 1</td><td>1</td></tr><tr><td></td><td>LAST와 같거나 클 경우</td><td>NULL</td></tr></tbody></table>

다음은 PRIOR, NEXT 함수의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
BEGIN
    DBMS_OUTPUT.PUT_LINE('First sunday is ' || my_sunday.PRIOR(2));
    DBMS_OUTPUT.PUT_LINE('Last sunday is ' || my_sunday.NEXT(1));
    my_sunday.DELETE(2);
    DBMS_OUTPUT.PUT_LINE('First sunday is ' || my_sunday.NEXT(1));
END;
/
```

다음은 실행 결과입니다.

```
First sunday is 1
Last sunday is 2
First sunday is 3
```

## **EXTEND 프러시저**

EXTEND 프러시저는 네스티드 테이블이나 배열의 크기를 늘리기 위해 사용됩니다.

사용하는 방법은 다음과 같이 세 가지가 있습니다.

<table><thead><tr><th width="242">방법</th><th>설명</th></tr></thead><tbody><tr><td>EXTEND</td><td>하나의 NULL 구성요소를 추가</td></tr><tr><td>EXTEND(n)</td><td>n개의 NULL 구성요소를 추가</td></tr><tr><td>EXTEND(m, n)</td><td>n번째 구성요소를 m개 추가</td></tr></tbody></table>

구성요소를 NOT NULL로 선언한 네스티드 테이블과 배열에서는 EXTEND(m, n)을 사용합니다. NULL 구성요소를 추가하는 EXTEND와 EXTEND(n)은 컴파일 단계에서 TBR-15081이 발생합니다.

배열에서 EXTEND 결과가 선언한 크기를 넘으면 **SUBSCRIPT\_OUTSIDE\_LIMIT** 예외 상황이 발생합니다(TBR-15111).

다음은 EXTEND 프러시저의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
    buf VARCHAR2(200) := '';
BEGIN
    DBMS_OUTPUT.PUT_LINE('Before extend = ' || my_sunday.COUNT);
    my_sunday.EXTEND(4, 2);
    DBMS_OUTPUT.PUT_LINE('After extend = ' || my_sunday.COUNT);
    FOR i IN 1 .. my_sunday.COUNT LOOP
        buf := buf || my_sunday(i) || ' ';
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('[' || buf || ']');
END;
/
```

다음은 실행 결과입니다. 2번째 구성요소인 9가 네 개 추가됩니다.

```
Before extend = 5
After extend = 9
[2 9 16 23 30 9 9 9 9 ]
```

## **TRIM 프러시저**

TRIM 프러시저는 배열이나 네스티드 테이블의 크기를 줄이기 위해 사용됩니다.

사용하는 방법은 다음과 같이 두 가지가 있습니다.

<table><thead><tr><th width="141">방법</th><th>설명</th></tr></thead><tbody><tr><td>TRIM</td><td>뒤에서부터 하나의 구성요소를 제거</td></tr><tr><td>TRIM(n)</td><td><ul><li>뒤에서부터 n개의 구성요소를 제거</li><li>n이 구성요소의 개수보다 크면 SUBSCRIPT_BEYOND_COUNT 예외 상황이 발생</li></ul></td></tr></tbody></table>

다음은 TRIM 프러시저의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
BEGIN
    DBMS_OUTPUT.PUT_LINE('Before trim = ' || my_sunday.COUNT);
    my_sunday.TRIM(2);
    DBMS_OUTPUT.PUT_LINE('After trim = ' || my_sunday.COUNT);
    my_sunday.TRIM(5);
EXCEPTION
    WHEN SUBSCRIPT_BEYOND_COUNT THEN
        DBMS_OUTPUT.PUT_LINE('TRIM(5) : SQLCODE = ' || SQLCODE);
END;
/
```

다음은 실행 결과입니다.

```
Before trim = 5
After trim = 3
TRIM(5) : SQLCODE = -15110
```

## **DELETE 프러시저**

DELETE 프러시저는 특정 인덱스의 구성요소를 제거하거나 전체 구성요소를 제거하기 위해 사용됩니다.

사용하는 방법은 다음과 같이 세 가지가 있습니다.

<table><thead><tr><th width="175">방법</th><th>설명</th></tr></thead><tbody><tr><td>DELETE</td><td>전체 구성요소를 제거</td></tr><tr><td>DELETE(n)</td><td><ul><li>네스티드 테이블 : 네스티드 테이블에서 n번째 구성요소를 제거</li><li>인덱스 테이블 : 키값이 n인 값을 제거</li></ul></td></tr><tr><td>DELETE(m, n)</td><td><ul><li>네스티드 테이블 또는 인덱스 테이블에서 m부터 n까지의 구성요소를 제거</li><li>m이 n보다 크거나 m과 n 중 하나라도 NULL이면 어떠한 값도 제거되지 않음</li></ul></td></tr></tbody></table>

다음은 DELETE 프러시저의 예입니다.

```
set serveroutput on
DECLARE
    TYPE sunday_tab IS TABLE OF PLS_INTEGER;
    my_sunday sunday_tab := sunday_tab(2, 9, 16, 23, 30);
BEGIN
    my_sunday.delete(2, 4);
    DBMS_OUTPUT.PUT_LINE('After delete(2, 4) = ' || my_sunday.COUNT);
    IF my_sunday.EXISTS(2) THEN
        DBMS_OUTPUT.PUT_LINE('Second sunday is ' || my_sunday(2));
    END IF;
    my_sunday.delete(4, 2);
    DBMS_OUTPUT.PUT_LINE('After delete(4, 2) = ' || my_sunday.COUNT);
    my_sunday.delete;
    DBMS_OUTPUT.PUT_LINE('After delete = ' || my_sunday.COUNT);
END;
/
```

다음은 실행 결과입니다. 두 번째 DELETE는 m이 n보다 커서 아무것도 제거하지 않습니다.

```
After delete(2, 4) = 2
After delete(4, 2) = 2
After delete = 0
```
