Dan*_*Dan 11 oracle plsql associative-array
我想在PL/SQL中执行SQL查询,并将结果填充到关联数组中,其中SQL中的一列成为关联数组中的键.例如,假设我有一个Person
带有列的表
PERSON_ID INTEGER PRIMARY KEY
PERSON_NAME VARCHAR2(50)
Run Code Online (Sandbox Code Playgroud)
...和价值观如下:
PERSON_ID | PERSON_NAME
------------------------
6 | Alice
15 | Bob
1234 | Carol
Run Code Online (Sandbox Code Playgroud)
我想批量收集此表TABLE OF VARCHAR2(50) INDEX BY INTEGER
,使得6
此关联数组中的键具有值Alice
等等.可以在PL/SQL中完成吗?如果是这样,怎么样?
Rob*_*cke 14
不,您必须使用2个集合(id,name)或其元素类型为记录的集合.
以下是后者的示例:
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;
Run Code Online (Sandbox Code Playgroud)
如果我们想在关联数组的索引中指定值,那么我们必须使用以下语法:
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>
Run Code Online (Sandbox Code Playgroud)
我们可以使用批量收集填充关联数组,但仅当索引是整数时,我们很乐意通过(隐式)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>
Run Code Online (Sandbox Code Playgroud)
公平地说,如果你需要使用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>
Run Code Online (Sandbox Code Playgroud)
众所周知,挂钟性能测试非常复杂.但是对于几百条记录,任何差异都不值得担心,当然在我们可能想要使用相关阵列的地方.
编辑2
@Dan说:
在我看来,想要查询一个相当大的行数到一个可用于恒定时间查找的数据结构应该是一个非常普遍的需要
这实际上取决于你对"一个体面的数字"的定义.是否真的存在许多情况,我们希望使用字符串索引填充具有数千行的关联数组?当我们得到这些数字时,普通的数据库表可能同样有用,特别是在带有结果集缓存的11g企业版上.
归档时间: |
|
查看次数: |
41486 次 |
最近记录: |