Oracle PL/SQL 컬렉션: 테이블별 Varray, 중첩 및 인덱스
⚡ 스마트 요약
PL/SQL 컬렉션은 동일한 데이터 형식의 요소들을 순서대로 묶어 놓은 것으로, 각 요소는 첨자를 통해 접근할 수 있습니다. 컬렉션에는 Varray, 중첩 테이블, 인덱스 기반 테이블의 세 가지 유형이 있으며, 크기가 고정되어 있는지, 첨자를 사용하는 방식, 데이터베이스에 저장할 수 있는지 여부에서 차이가 있습니다.
컬렉션이란 무엇입니까?
컬렉션은 특정 데이터 형식의 요소들을 순서대로 모아 놓은 것입니다. 단순한 데이터 형식의 컬렉션일 수도 있고, 사용자 정의 데이터 형식이나 레코드 형식과 같은 복잡한 데이터 형식의 컬렉션일 수도 있습니다.
컬렉션에서 각 요소는 요소라는 용어로 식별됩니다. “아래첨자.” 각 항목에는 고유한 첨자가 할당되며, 해당 고유 첨자를 참조하여 데이터를 조작하거나 가져올 수 있습니다.
컬렉션은 동일한 유형의 대량 데이터를 처리하거나 조작해야 할 때 가장 유용합니다. 컬렉션은 'BULK' 옵션을 사용하여 전체를 한꺼번에 채우고 조작할 수 있습니다. Oracle.
컬렉션은 아래와 같이 구조, 첨자 및 저장 방식에 따라 분류됩니다.
- 인덱스 기반 테이블(연관 배열이라고도 함)
- 중첩된 테이블
- 바라이
컬렉션 내의 데이터는 언제든지 컬렉션 이름, 첨자, 필드 또는 열 이름이라는 세 가지 용어로 참조할 수 있습니다. 예를 들어, " ( ). 아래 섹션에서 이러한 컬렉션 카테고리에 대해 자세히 알아보실 수 있습니다.
컬렉션 유형 한눈에 보기
세 가지 수집 유형은 각각 다른 장단점을 가지고 있습니다. 아래 표는 각 유형을 자세히 살펴보기 전에 비교 분석한 것입니다.
| 아래 | 바레이 | 중첩 테이블 | 테이블별 색인 |
|---|---|---|---|
| 중량 | 고정 상한 | 제한 없음 | 제한 없음 |
| 첨자 | 숫자 | 숫자 | 정수 또는 문자열 |
| 밀도 | 항상 밀도가 높음 | 밀집된 또는 드문드문한 | 항상 드문드문 |
| 데이터베이스에 저장됨 | 가능 | 가능 | 아니 |
| 초기화가 필요합니다 | 가능 | 가능 | 아니 |
바라이
Varray는 배열 크기가 고정되어 있고 초과할 수 없는 컬렉션입니다. Varray의 첨자는 숫자 값입니다. Varray의 속성은 다음과 같습니다.
- 최대 크기는 고정되어 있습니다.
- 아래첨자 '1'부터 순차적으로 채워집니다.
- 이 컬렉션 유형은 항상 밀집되어 있으므로 개별 배열 요소를 삭제할 수 없습니다. Varray는 전체를 삭제하거나 끝부분부터 잘라낼 수 있습니다.
- 밀도가 항상 높기 때문에 유연성이 매우 낮습니다.
- 배열 크기를 알고 있고 모든 요소에 대해 유사한 작업을 수행하는 경우에 더 적합합니다.
- 수집의 아래첨자와 개수는 항상 일정하게 유지됩니다.
- 컬렉션은 사용하기 전에 반드시 초기화해야 합니다. 초기화되지 않은 컬렉션에 대해 EXISTS를 제외한 모든 작업을 수행하면 오류가 발생합니다.
- 데이터베이스 전체에서 볼 수 있는 데이터베이스 객체로 생성하거나, 서브프로그램 내에서만 사용하기 위해 서브프로그램 내부에 생성할 수 있습니다.
아래 그림은 Varray(밀집형)의 메모리 할당 방식을 설명합니다.
| 첨자 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 가치관 | Xyz | Dfv | SDE | Cxs | VBC | Nhu는 | Qwe |
VARRAY 구문:
TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
- 위 구문에서 type_name은 지정된 크기 제한에 따라 'DATA_TYPE' 형식의 VARRAY로 선언됩니다. 데이터 형식은 단순 또는 복합 형식일 수 있습니다.
중첩 테이블
중첩 테이블은 배열 크기가 고정되어 있지 않은 컬렉션입니다. 숫자 첨자 형식을 사용합니다. 중첩 테이블 형식에 대한 자세한 내용은 다음을 참조하세요.
- 중첩 테이블에는 크기 제한이 없습니다.
- 상한값이 고정되어 있지 않으므로, 사용 전에 매번 'EXTEND' 키워드를 사용하여 메모리를 확장해야 합니다.
- 아래첨자 '1'부터 순차적으로 채워집니다.
- 이 수집 유형은 둘 다 가능합니다. 조밀하고 희박한우리는 이를 밀집된 형태로 생성할 수도 있고, 개별 요소를 무작위로 삭제하여 희소한 형태로 만들 수도 있습니다.
- 배열 요소를 삭제하는 데 더 많은 유연성을 제공합니다.
- 해당 값은 시스템에서 생성된 데이터베이스 테이블에 저장되며, 선택 쿼리를 사용하여 값을 가져올 수 있습니다.
- 아래첨자와 개수는 다양할 수 있습니다.
- 컬렉션은 사용하기 전에 반드시 초기화해야 합니다. 초기화되지 않은 컬렉션에 대해 EXISTS를 제외한 모든 작업을 수행하면 오류가 발생합니다.
- 데이터베이스 전체에서 볼 수 있는 데이터베이스 객체로 생성하거나, 서브프로그램 내에서만 사용하기 위해 서브프로그램 내부에 생성할 수 있습니다.
아래 그림은 중첩 테이블(밀집 및 희소 테이블)의 메모리 할당을 설명합니다. 빈 요소 공간은 희소 요소를 나타냅니다.
| 첨자 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 값(밀도) | Xyz | Dfv | SDE | Cxs | VBC | Nhu는 | Qwe |
| 값(희소) | Qwe | ASD | 아프간 | ASD | WER |
중첩 테이블의 구문:
TYPE <type_name> IS TABLE OF <DATA_TYPE>;
- 위 구문에서 type_name은 'DATA_TYPE' 형식의 중첩 테이블 컬렉션으로 선언됩니다. 데이터 형식은 단순 또는 복합 형식일 수 있습니다.
테이블별 색인
인덱스 테이블은 배열 크기가 고정되어 있지 않은 컬렉션입니다. 다른 컬렉션 유형과 달리 인덱스 테이블의 첨자는 사용자가 정의할 수 있습니다. 인덱스 테이블의 속성은 다음과 같습니다.
- 첨자는 정수 또는 문자열일 수 있습니다. 컬렉션을 생성할 때 첨자 유형을 명시해야 합니다.
- 이러한 컬렉션은 순차적으로 저장되지 않습니다.
- 그들은 본질적으로 항상 드물다.
- 배열 크기는 고정되어 있지 않습니다.
- 이러한 데이터는 데이터베이스 열에 저장할 수 없습니다. 특정 세션 내에서 생성되고 사용됩니다.
- 이를 통해 아래첨자를 유지하는 데 더 많은 유연성을 얻을 수 있습니다.
- 아래첨자는 음수 순서일 수 있습니다.
- 이는 동일한 하위 프로그램 내에서 사용되는 비교적 작은 컬렉션 값에 더 적합합니다.
- 사용 전에 초기화할 필요가 없습니다.
- 데이터베이스 객체로는 생성할 수 없으며, 서브프로그램 내부에서만 생성할 수 있습니다.
- 이 수집 유형에서는 BULK COLLECT를 사용할 수 없습니다. 각 레코드에 대해 첨자를 명시적으로 지정해야 하기 때문입니다.
아래 그림은 인덱스 기반 테이블(희소 테이블)의 메모리 할당을 설명합니다. 빈 요소 공간은 희소 요소를 나타냅니다.
| 아래첨자(varchar) | 먼저 | 둘째 | THIRD | 네번째 | 다섯 번째 | 여섯 번째 | 제칠 |
| 값(희소) | Qwe | ASD | 아프간 | ASD | WER |
테이블을 기준으로 색인을 생성하는 구문:
TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
- 위 구문에서 type_name은 'DATA_TYPE' 형식의 인덱스 기반 테이블 컬렉션으로 선언되었습니다. 첨자 변수는 최대 크기가 10인 VARCHAR2 형식으로 지정되었습니다.
컬렉션의 생성자와 초기화 개념
생성자는 내장 함수입니다. Oracle 객체 또는 컬렉션과 동일한 이름을 가진 생성자들입니다. 이러한 생성자들은 세션에서 객체 또는 컬렉션이 처음 참조될 때마다 먼저 실행됩니다. 컬렉션 컨텍스트에서 생성자에 대한 중요한 세부 정보는 다음과 같습니다.
- 컬렉션의 경우, 컬렉션을 초기화하려면 이러한 생성자를 명시적으로 호출해야 합니다.
- Varray와 중첩 테이블은 프로그램에서 참조되기 전에 이러한 생성자를 통해 초기화되어야 합니다.
- 생성자는 컬렉션(Varray 제외)에 대한 메모리 할당을 암묵적으로 확장하므로 컬렉션에 변수를 할당할 수도 있습니다.
- 생성자를 통해 값을 할당하는 것은 컬렉션을 희소하게 만들지 않습니다.
수집방법
Oracle 컬렉션을 조작하고 작업하는 데 사용할 수 있는 다양한 함수를 제공합니다. 이러한 함수는 컬렉션의 여러 속성을 확인하고 수정할 수 있습니다. 아래 표는 다양한 함수와 그 설명을 보여줍니다.
| 방법 | 기술설명 | 통사론 |
|---|---|---|
| 존재함(n) | 불리언 값을 반환합니다. n번째 요소가 존재하면 TRUE를, 그렇지 않으면 FALSE를 반환합니다. 초기화되지 않은 컬렉션에는 EXISTS만 사용할 수 있습니다. | .EXISTS(요소_위치) |
| COUNT | 컬렉션에 있는 요소의 총 개수를 반환합니다. | .세다 |
| 제한 | 컬렉션의 최대 크기를 반환합니다. Varray의 경우 고정 크기를 반환하고, 중첩 테이블 및 인덱스 기반 테이블의 경우 NULL을 반환합니다. | .한계 |
| 먼저 | 컬렉션의 첫 번째 첨자의 값을 반환합니다. | .첫 번째 |
| LAST | 컬렉션의 마지막 첨자의 값을 반환합니다. | .마지막 |
| 이전 (n) | n번째 요소의 바로 앞 첨자를 반환합니다. 첨자가 없으면 NULL을 반환합니다. | .이전(n) |
| 다음(n) | n번째 요소의 다음 첨자를 반환합니다. 첨자가 없으면 NULL을 반환합니다. | .다음(n) |
| 넓히다 | 컬렉션의 끝에 있는 요소 하나를 확장합니다. | .연장하다 |
| 확장(n) | 컬렉션의 끝에 n개의 요소를 추가합니다. | .EXTEND(n) |
| 확장(n,i) | 컬렉션의 끝에 i번째 요소의 n개 복사본을 추가합니다. | .EXTEND(n,i) |
| 정돈 | 컬렉션의 끝에서 요소 하나를 제거합니다. | .손질 |
| 트림(n) | 컬렉션의 끝에서 n개의 요소를 제거합니다. | .트림(n) |
| 삭제 | 컬렉션에서 모든 요소를 삭제하여 빈 컬렉션으로 만듭니다. | .삭제 |
| 삭제(n) | n번째 요소를 삭제합니다. n번째 요소가 NULL인 경우 아무 작업도 수행하지 않습니다. | .DELETE(n) |
| 삭제(m,n) | 컬렉션에서 m번째부터 n번째까지의 요소를 삭제합니다. | .DELETE(m,n) |
예시 1: 서브프로그램 수준의 레코드 유형
이 예제에서는 '를 사용하여 컬렉션을 채우는 방법을 보여줍니다.대량 수집그리고 컬렉션 데이터를 참조하는 방법은 무엇인가요?
DECLARE TYPE emp_det IS RECORD ( EMP_NO NUMBER, EMP_NAME VARCHAR2(150), MANAGER NUMBER, SALARY NUMBER ); TYPE emp_det_tbl IS TABLE OF emp_det; guru99_emp_rec emp_det_tbl:= emp_det_tbl(); BEGIN INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1000,'AAA',25000,1000); INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1001,'XXX',10000,1000); INSERT INTO emp (emp_no, emp_name, salary, manager) VALUES (1002,'YYY',15000,1000); INSERT INTO emp (emp_no,emp_name,salary, manager) VALUES (1003,'ZZZ',7500,1000); COMMIT; SELECT emp_no,emp_name,manager,salary BULK COLLECT INTO guru99_emp_rec FROM emp; dbms_output.put_line ('Employee Detail'); FOR i IN guru99_emp_rec.FIRST..guru99_emp_rec.LAST LOOP dbms_output.put_line ('Employee Number: '||guru99_emp_rec(i).emp_no); dbms_output.put_line ('Employee Name: '||guru99_emp_rec(i).emp_name); dbms_output.put_line ('Employee Salary:'|| guru99_emp_rec(i).salary); dbms_output.put_line('Employee Manager Number:'||guru99_emp_rec(i).manager); dbms_output.put_line('--------------------------------'); END LOOP; END; /
Code 설명
- Code 2-8행: 레코드 유형 'emp_det'는 NUMBER, VARCHAR2, NUMBER, NUMBER 데이터 형식의 emp_no, emp_name, manager, salary 열로 선언되었습니다.
- Code 9행: 레코드 유형 요소 'emp_det'의 컬렉션 'emp_det_tbl'을 생성합니다.
- Code 10행: 변수 'guru99_emp_rec'를 'emp_det_tbl' 타입으로 선언하고 null 생성자로 초기화합니다.
- Code 12-15행: 샘플 데이터를 'emp' 테이블에 삽입합니다.
- Code 16행: 삽입 트랜잭션을 커밋합니다.
- Code 17행: 'emp' 테이블에서 레코드를 가져와 "BULK COLLECT"를 사용하여 컬렉션 변수에 일괄적으로 채웁니다. 이제 변수 'guru99_emp_rec'에는 'emp' 테이블에 있는 모든 레코드가 포함됩니다.
- Code 19-26행: 컬렉션의 모든 레코드를 하나씩 출력하도록 'FOR' 루프를 설정합니다. 컬렉션 메서드인 FIRST와 LAST는 레코드 수의 하한과 상한으로 사용됩니다. 고리.
출력: 위 코드를 실행하면 다음과 같은 출력이 나타납니다.
Employee Detail Employee Number: 1000 Employee Name: AAA Employee Salary: 25000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1001 Employee Name: XXX Employee Salary: 10000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1002 Employee Name: YYY Employee Salary: 15000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1003 Employee Name: ZZZ Employee Salary: 7500 Employee Manager Number: 1000 ----------------------------------------------


