PL/SQL 대량 수집을 스파스 키를 사용하여 연관 배열로 수집
PL/SQL 내부에서 SQL 쿼리를 실행하여 결과를 연관 배열로 채우고 SQL의 열 중 하나가 연관 배열의 키가 됩니다.예를 들어 테이블이 있다고 가정합니다.Person
열이 있는
PERSON_ID INTEGER PRIMARY KEY
PERSON_NAME VARCHAR2(50)
...다음과 같은 값이 있습니다.
PERSON_ID | PERSON_NAME
------------------------
6 | Alice
15 | Bob
1234 | Carol
나는 이 테이블을 대량으로 수집하고 싶습니다.TABLE OF VARCHAR2(50) INDEX BY INTEGER
열쇠가 되도록6
이 연상 배열에서 값은 다음과 같습니다.Alice
등등.PL/SQL에서 수행할 수 있습니까?만약 그렇다면, 어떻게?
아니요, 두 개의 컬렉션(ID, 이름) 또는 요소 유형이 레코드인 컬렉션을 사용해야 합니다.
후자의 예는 다음과 같습니다.
cursor getPersonsCursor is
SELECT ID, Name
FROM Persons
WHERE ...;
subtype TPerson is getPersonsCursor%rowtype;
type TPersonList is table of TPerson;
persons TPersonList;
begin
open getPersonsCursor;
fetch getPersonsCursor
bulk collect into persons;
close getPersonsCursor;
if persons.Count > 0 then
for i in persons.First .. persons.Last loop
yourAssocArray(persons(i).ID) := persons(i).Name;
end loop;
end if;
연관 배열의 인덱스에 값을 지정하려면 다음 구문을 사용해야 합니다.
SQL> declare
2 type n_array is table of varchar2(30)
3 index by binary_integer;
4 emp_names n_array;
5 begin
6 for r in ( select ename, empno from emp )
7 loop
8 emp_names(r.empno) := r.ename;
9 end loop;
10
11 dbms_output.put_line('count='||emp_names.count()
12 ||'::last='||emp_names.last());
13 dbms_output.put_line(emp_names(8085));
14
15 end;
16 /
count=19::last=8085
TRICHLER
PL/SQL procedure successfully completed.
SQL>
대량 수집을 사용하여 연관 배열을 채울 수 있지만 인덱스가 정수이고 (암묵적인) ROWNUM(즉, 희소 키가 아닌)을 사용하여 인덱싱할 수 있습니다.
SQL> declare
2 type n_array is table of varchar2(30)
3 index by binary_integer;
4 emp_names n_array;
5 begin
6 select ename
7 bulk collect into emp_names
8 from emp ;
9
10 dbms_output.put_line('count='||emp_names.count()
11 ||'::last='||emp_names.last());
12 dbms_output.put_line(emp_names(19));
13
14 end;
15 /
count=19::last=19
FEUERSTEIN
PL/SQL procedure successfully completed.
SQL>
공정하게 말하자면, BULK COLLECT를 사용해야 하는 경우에는 연관 배열에 적합한 것보다 더 많은 데이터를 처리하고 있을 수 있습니다.
편집
두 가지 접근 방식에 대한 저렴한 성능 테스트:
SQL> declare
2 type n_array is table of varchar2(30)
3 index by binary_integer;
4 emp_names n_array;
5 s_time pls_integer;
6 e_time pls_integer;
7 begin
8 s_time := dbms_utility.get_time;
9 select ename
10 bulk collect into emp_names
11 from big_emp
12 where rownum <= 500;
13 dbms_output.put_line('bulk collect elapsed time = '
14 ||to_char(dbms_utility.get_time - s_time));
15 s_time := dbms_utility.get_time;
16 for r in ( select ename, empno from big_emp
17 where rownum <= 500 )
18 loop
19 emp_names(r.empno) := r.ename;
20 end loop;
21 dbms_output.put_line('sparse array elapsed time = '
22 ||to_char(dbms_utility.get_time - s_time));
23 end;
24 /
bulk collect elapsed time = 0
sparse array elapsed time = 0
PL/SQL procedure successfully completed.
SQL>
벽시계 성능 테스트는 거친 것으로 악명이 높습니다.하지만 수백 개의 기록에 대해서는, 어떤 차이도 걱정할 가치가 없을 것 같습니다. 확실히 우리가 연상배열을 사용하고 싶어하는 곳의 맥락에서 말입니다.
편집 2
@댄이 말했습니다.
일정한 시간 검색에 사용할 수 있는 데이터 구조에 적절한 크기의 행 수를 쿼리하는 것이 상당히 일반적인 요구 사항인 것 같습니다.
그것은 정말로 "적당한 크기의 숫자"에 대한 당신의 정의에 달려 있습니다.수천 개의 행과 문자열 인덱스가 있는 연관 배열을 채우는 경우가 정말 그렇게 많습니까?이러한 수치에 도달하면 일반적인 데이터베이스 테이블도 마찬가지로 유용할 수 있습니다. 특히 11g Enterprise Edition에서는 결과 집합 캐싱이 가능합니다.
언급URL : https://stackoverflow.com/questions/2715736/pl-sql-bulk-collect-into-associative-array-with-sparse-key
'source' 카테고리의 다른 글
Ajax.ActionLink가 작동하지 않습니다. 응답.IsAjaxRequest()는 항상 false입니다. (0) | 2023.07.26 |
---|---|
Spring WebFlux WebClient를 조롱하는 방법은 무엇입니까? (0) | 2023.07.26 |
jQuery AJAX vs.업데이트 패널 (0) | 2023.07.26 |
mysql에서 '보기에서 표 만들기' 구문이 쉽습니까? (0) | 2023.07.26 |
'<' 연산자가 예약된 PowerShell 오류입니다. (0) | 2023.07.26 |