您可以使用SELECT my_record_type(column_value) BULK COLLECT INTO v_table from table(v_hash)
。但爲了使用它,您必須在函數之外創建my_hash_type(作爲包裝規格中的類型或,以便SQL引擎可以看到它),否則您將收到PLS-00642: local collection types not allowed in SQL statements
。
CREATE OR REPLACE TYPE my_hash_type is table OF VARCHAR2(10);
/
set serveroutput on
declare
--type my_hash_type is table OF VARCHAR2(10);
v_hash my_hash_type := my_hash_type();
v_table my_table_type;
i NUMBER;
begin
null ;
for n in 60..75 loop
V_hash.extend(1);
V_hash(v_hash.count) := chr(n) ;
end loop ;
select my_record_type(column_value)
bulk collect into v_table
from table(v_hash) ;
for n in 1..v_table.count loop
dbms_output.put_line(n || ':>' || v_table(n).name);
end loop ;
--PLS-00642: local collection types not allowed in SQL statements
end ;
1:><
2:>=
3:>>
4:>?
5:>@
6:>A
7:>B
8:>C
9:>D
10:>E
11:>F
12:>G
13:>H
14:>I
15:>J
16:>K
有一些例子看看here和here和諸如此類的東西
定時差(based on this methodology#分別是在百分之一秒爲單位)
pl/sql context switch (as described above)
44
42
43
42
loop fill (with type defined outside of block) --A distinct CREATE TYPE on Oracle level
18
18
18
18
loop fill (with type defined within block) --Type created within the Anon. block
23
22
24
22
(上述時間試驗是變化基於此代碼:
set serveroutput on
declare
--type my_hash_type is table of my_record_type -index by pls_integer;
v_hash my_hash_type := my_hash_type();
v_table my_table_type;
i NUMBER;
time_before BINARY_INTEGER;
time_after BINARY_INTEGER;
begin
time_before := DBMS_UTILITY.GET_TIME;
for n in 0..15000 loop
V_hash.extend(1);
V_hash(v_hash.count) := my_record_type(n) ;
end loop ;
select my_record_type(column_value)
bulk collect into v_table
from table(v_hash) ;
/*
v_table := my_table_type();
for n in 1..V_hash.count loop
v_table.extend(1);
v_table(v_table.count) := v_hash(n) ;
--dbms_output.put_line(n || ':>' || v_table(n).name);
end loop ;*/
--for n in 1..v_table.count loop
-- dbms_output.put_line(n || ':>' || v_table(n).name);
--end loop ;
time_after := DBMS_UTILITY.GET_TIME;
DBMS_OUTPUT.PUT_LINE (time_after - time_before);
--PLS-00642: local collection types not allowed in SQL statements
end ;
/
因此循環填充速度提高了50%,但時間差異仍然很小(這裏是過早優化和避免某些事情之間的平衡,因爲它可能太長,我建議您對實際數據進行時間測試以找到解決方案最適合)。
我能想到的唯一的其他「優雅」解決方案是TREAT,但您會注意到它需要一個子類型/超類型解決方案,它必須位於對象類型上(我無法讓它在Varray/Assoc。Array類型 - 希望我錯了!)
它看起來像你不關心'v_hash'中的實際鍵*自己*,只是他們的順序。如果是這樣的話,爲什麼要使用INDEX BY表呢? – Dan 2011-06-06 17:04:46
如果'MY_HASH_TYPE'是一個'MY_RECORD_TYPE'表,就像'MY_TABLE_TYPE'一樣,爲什麼不直接聲明V_HASH類型爲'MY_TABLE_TYPE'?然後,你可以取消V_TABLE並只返回V_HASH。除非您的示例代碼中缺少您的業務邏輯的某些細微之處。 – APC 2011-06-06 19:01:02
@APC:我在' - 這裏使用了一些業務邏輯中的哈希部分:) – schurik 2011-06-07 08:46:02