我想在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中完成吗?如果是这样,怎么样?
答案 0 :(得分: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;
答案 1 :(得分:6)
如果我们想在关联数组的索引中指定值,那么我们必须使用以下语法:
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 with resultset caching上。